Есть две концепции, которые близки, но их не следует путать: IDENTITY
и PRIMARY KEY
Каждая таблица (за исключением редких условий) должна иметь PRIMARY KEY
, то есть значение или набор значений, которые однозначно идентифицируют строку.
См. здесь для обсуждения почему.
IDENTITY
- это свойство столбца в SQL Server
, что означает, что столбец будет автоматически заполняться приращением значений.
Из-за природы этого свойства значения этого столбца по своей природе UNIQUE
.
Однако в столбце IDENTITY
автоматически не создается ограничение UNIQUE
или индекс UNIQUE
, и после выдачи SET IDENTITY_INSERT ON
можно вставить повторяющиеся значения в столбец IDENTITY
, если это не было явным UNIQUE
ограничено.
Столбец IDENTITY
не обязательно должен быть PRIMARY KEY
, но чаще всего он используется для заполнения суррогата PRIMARY KEY
s
Это может или не может быть полезно в любом конкретном случае.
Поэтому ответ на ваш вопрос:
Вопрос: должна ли каждая таблица в базе данных иметь поле IDENTITY, которое используется в качестве PK?
это:
Нет. Есть случаи, когда таблица базы данных НЕ должна иметь поле IDENTITY
как PRIMARY KEY
.
Три случая приходят мне на ум, когда не лучшая идея иметь IDENTITY
как PRIMARY KEY
:
- Если ваш
PRIMARY KEY
составной (как в таблицах ссылок «многие ко многим»)
- Если ваш
PRIMARY KEY
натуральный (например, код штата)
- Если ваш
PRIMARY KEY
должен быть уникальным для всех баз данных (в этом случае вы используете GUID
/ UUID
/ NEWID
)
Все эти случаи подразумевают следующее условие:
У вас не должно быть IDENTITY
, когда вы заботитесь о значениях вашего PRIMARY KEY
и явно вставляете их в свою таблицу.
Обновление:
Таблицы ссылок «многие ко многим» должны иметь пару id
с таблицей, которую они связывают как составной ключ.
Это естественный составной ключ, который вы уже должны использовать (и создаете UNIQUE
), так что нет смысла генерировать суррогатный ключ для этого.
Я не понимаю, зачем вам ссылаться на таблицу ссылок many-to-many
из любой другой таблицы, кроме таблиц, на которые они ссылаются, но давайте предположим, что у вас есть такая необходимость.
В этом случае вы просто ссылаетесь на таблицу ссылок по составному ключу.
Этот запрос:
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
гораздо эффективнее, чем этот:
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
, по понятным причинам.