gzip, выкачивают + некоторые данные заголовка/нижнего колонтитула, как контрольная сумма и длина, и т.д. Таким образом, они не совместимы в том смысле, что один метод может использовать поток от другого, но они используют тот же алгоритм сжатия.
There are two concepts that are close but should not be confused: IDENTITY
and PRIMARY KEY
Every table (except for the rare conditions) should have a PRIMARY KEY
, that is a value or a set of values that uniquely identify a row.
See here for discussion why.
IDENTITY
is a property of a column in SQL Server
which means that the column will be filled automatically with incrementing values.
Due to the nature of this property, the values of this column are inherently UNIQUE
.
However, no UNIQUE
constraint or UNIQUE
index is automatically created on IDENTITY
column, and after issuing SET IDENTITY_INSERT ON
it's possible to insert duplicate values into an IDENTITY
column, unless it had been explicity UNIQUE
constrained.
The IDENTITY
column should not necessarily be a PRIMARY KEY
, but most often it's used to fill the surrogate PRIMARY KEY
s
It may or may not be useful in any particular case.
Therefore, the answer to your question:
The question: should every table in a database have an IDENTITY field that's used as the PK?
is this:
IDENTITY
field as a PRIMARY KEY
.Three cases come into my mind when it's not the best idea to have an IDENTITY
as a PRIMARY KEY
:
PRIMARY KEY
is composite (like in many-to-many link tables)PRIMARY KEY
is natural (like, a state code)PRIMARY KEY
should be unique across databases (in this case you use GUID
/ UUID
/ NEWID
)All these cases imply the following condition:
IDENTITY
when you care for the values of your PRIMARY KEY
and explicitly insert them into your table.Update:
Many-to-many link tables should have the pair of id
's to the table they link as the composite key.
It's a natural composite key which you already have to use (and make UNIQUE
), so there is no point to generate a surrogate key for this.
I don't see why would you want to reference a many-to-many
link table from any other table except the tables they link, but let's assume you have such a need.
In this case, you just reference the link table by the composite key.
This query:
CREATE TABLE a (id, data)
CREATE TABLE b (id, data)
CREATE TABLE ab (a_id, b_id, PRIMARY KEY (a_id, b_id))
CREATE TABLE business_rule (id, a_id, b_id, FOREIGN KEY (a_id, b_id) REFERENCES ab)
SELECT *
FROM business_rule br
JOIN a
ON a.id = br.a_id
is much more efficient than this one:
CREATE TABLE a (id, data)
CREATE TABLE b (id, data)
CREATE TABLE ab (id, a_id, b_id, PRIMARY KEY (id), UNIQUE KEY (a_id, b_id))
CREATE TABLE business_rule (id, ab_id, FOREIGN KEY (ab_id) REFERENCES ab)
SELECT *
FROM business_rule br
JOIN a_to_b ab
ON br.ab_id = ab.id
JOIN a
ON a.id = ab.a_id
, for obvious reasons.
I'm a firm believer that natural keys are often far worse than artificial keys because you often have no control over whether they will change which can cause horrendous data integrity or performance problems.
However, there are some (very few) natural keys that make sense without being an identity field (two-letter state abbreviation comes to mind, it is extremely rare for these official type abbreviations to change.)
Any table which is a join table to model a many to many relationship probably also does not need an additional identity field. Making the two key fields together the primary key will work just fine.
Other than that I would, in general, add an identity field to most other tables unless given a compelling reason in that particular case not to. It is a bad practice to fail to create a primary key on a table or if you are using surrogate keys to fail to place a unique index on the other fields needed to guarantee uniqueness where possible (unless you really enjoy resolving duplicates).
Каждая таблица должна иметь некоторый набор полей, однозначно идентифицирующих ее. Наличие или отсутствие поля числового идентификатора отдельно от полей данных будет зависеть от домена, который вы пытаетесь моделировать. Не все данные легко попадают в парадигму «единого числового идентификатора», и поэтому было бы неуместно применять ее принудительно. Учитывая это, многие данные легко вписываются в эту парадигму и, как таковые, требуют такого идентификатора. Нет однозначного ответа, чтобы всегда делать X в любой среде программирования, и это еще один пример.
Almost always yes. I generally default to including an identity field unless there's a compelling reason not to. I rarely encounter such reasons, and the cost of the identity field is minimal, so generally I include.
Only thing I can think of off the top of my head where I didn't was a highly specialized database that was being used more as a datastore than a relational database where the DBMS was being used for nearly every feature except significant relational modelling. (It was a high volume, high turnover data buffer thing.)
I can't think of any drawback about having an ID field in each table. Providing your the type of your ID field provides enough space for your table to grow.
However, you don't necessarily need a single field to ensure the identity of your rows. So no, a single ID field is not mandatory.
Primary and Foreign Keys can consist not only of one field, but of multiple fields. This is typical for tables implementing a N-N relationship.
You can perfectly have PRIMARY KEY (fa, fb)
on your table:
CREATE TABLE t(fa INT , fb INT);
ALTER TABLE t ADD PRIMARY KEY(fa , fb);
Нет. Всякий раз, когда у вас есть таблица с искусственным столбцом идентичности, вам также необходимо определить естественный первичный ключ для таблицы и убедиться, что для этого набора столбцов также существует уникальное ограничение, чтобы вы не получили две идентичные друг другу строки. случайно из бессмысленного столбца идентичности.
Добавление столбца идентичности не является бесплатным. Добавление ненужного столбца идентификатора в таблицу связано с накладными расходами - обычно 4 байта на строку хранилища для значения идентификатора плюс целый дополнительный индекс (который, вероятно, будет весить 8–12 байтов на строку плюс накладные расходы). Также требуется немного времени для разработки наиболее экономичного плана запроса, поскольку для каждой таблицы есть дополнительный индекс. Конечно, если стол маленький, а машина большая, эти накладные расходы не критичны, но для самых больших систем они имеют значение.
Yes, for the vast majority of cases.
Edge cases or exceptions might be things like:
But other than that, I think there is no good reason against having a primary key to uniquely identify each row in a table, and in my opinion, using an IDENTITY field is one of the best choices (I prefer surrogate keys over natural keys - they're more reliable, stable, never changing etc.).
Marc
Recognize the distinction between an Identity field and a key... Every table should have a key, to eliminate the data corruption of inadvertently entering multiple rows that represent the same 'entity'. If the only key a table has is a meaningless surrogate key, then this function is effectively missing.
otoh, No table 'needs' an identity, and certainly not every table benefits from one... Examples are: A table with a short and functional key, a table which does not have any other table referencing it through a foreign Key, or a table which is in a one to zero-or-one relationship with another table... none of these need an Identity
Я бы сказал, что если вы можете найти простой естественный ключ в своей таблице (например, один столбец), используйте его как ключ вместо столбца идентификации.
Я обычно даю каждая таблица имеет какой-то уникальный идентификатор, естественный или сгенерированный, потому что тогда мне гарантируется , что каждая строка каким-то образом однозначно идентифицируется.
Лично я избегаю IDENTITY (увеличение столбцов идентификаторов, например 1, 2, 3, 4) столбики как чума. Они вызывают много хлопот, особенно если вы удалите строки из этой таблицы. Вместо этого я использую сгенерированные uniqueidentifiers, если в таблице нет естественного ключа.
В любом случае, я не знаю, является ли это общепринятой практикой, просто мне кажется правильным. YMMV.
Это зависит от того, как ваш EXE использует классы из DLL. Добавление новых классов не должно влиять на существующие точки входа. Однако, помимо этого, любое следующее повлияет на размер и / или макет объекта: разработан, нормализован и т. д., тогда у вас не будет столбцов идентификаторов.
Вы определили естественные и потенциальные ключи для ваших таблиц.
Вы можете выбрать суррогатный ключ из-за физической архитектуры (например, узкий, числовой, строго монотонно возрастает), скажем, потому что использование столбца nvarchar (100) не является хорошей идеей (все еще требуется уникальное ограничение).
Или из-за идеологии: они привлекают разработчиков объектно-ориентированного программирования, которых я нашел.
Хорошо, допустим, Столбцы идентификаторов. По мере того, как ваша база данных становится более сложной, скажем, на несколько слоев, как вы можете напрямую подключать родительские таблицы и таблицы grand-.child. Вы не можете: вам всегда нужны промежуточные таблицы и хорошо проиндексированные столбцы PK-FL. С составным ключом это все для вас ...
Не поймите меня неправильно: я их использую. Но я знаю, почему я их использую ...
Edit:
Мне было бы интересно сопоставить "Always ID"