Что лучше, иметь первичный ключ, состоящий из целого числа и внешнего ключа, или иметь автоинкремент первичного ключа и внешний ключ?

#sql #database #postgresql #database-design #relational-database

#sql #База данных #postgresql #database-design #реляционная база данных

Вопрос:

У меня проблема, администратор базы данных имеет следующую структуру:

введите описание изображения здесь

Как вы можете видеть, первичный ключ таблицы TCModulo является составным ключом ID_modulo и ID_sistema , который является внешним ключом таблицы TCSistemas .

Я думаю, что лучше, чтобы поле ID_modulo из таблицы TCModulo было первичным ключом с ограничением auto_increment, а поле ID_sistema должно быть только внешним ключом.

Какой из них лучше?

Комментарии:

1. Лучше с точки зрения чего? Чистота базы данных? Эффективность? Гибкость? Стоимость? Путаница?

2. Речь не о том, какой из них лучше . Речь идет о том, какой первичный ключ является правильным. ID_modulo Создает первичный ключ? Если это так, то неправильно включать ID_sistema в PK. Если ID_sistema необходимо создать PK, то он должен быть включен. Первичный ключ в Википедии

3. ID_modulo может быть первичным ключом в соответствии с другим соглашением о таблицах, требование состоит в том, чтобы в одной системе было много модулей, поле ID_sistema является первичным ключом таблицы TCsistema, поэтому я не понимаю, почему ID_modulo и ID_sistema являются первичным ключом таблицы TCmodulo, администратор db утверждает, что это для организации данных, говоря о чистоте, эффективности и гибкости базы данных

4. @ClodoaldoNeto amp; kentverger: К сожалению, эта статья в вики полна неточностей и заблуждений.

Ответ №1:

Является ли PK TCmodulo (ID_modulo) или (ID_modulo,ID_sistema), зависит от того, что содержится в таблице. Мы не можем ответить на ваш вопрос, пока вы не сообщите нам. Предположительно, значение ID_modulo в строке — это то, как вы ссылаетесь на некоторый модуль. Вы должны рассказать нам, как это сделать. Но после этого (для каждого столбца) (и учитывая, какие ситуации могут возникнуть) не остается выбора в отношении того, какие наборы столбцов являются кандидатами на первичный ключ.

Набор столбцов, значения подстроки которых уникальны в таблице, называется суперключем. Любая подстрока, содержащая уникальную подстроку, уникальна. Таким образом, любой набор столбцов, содержащих суперключ, является суперключом. Подстрока, которая не содержит (меньшую) уникальную подстроку, называется ключом-кандидатом. Таким образом, суперключ, который не содержит суперключей (меньшего размера), является ключом-кандидатом. В качестве первичного ключа выбирается один из ключей-кандидатов таблицы.

Если ID_modulo однозначно определяет модуль во всем приложении, то (ID_modulo) был бы уникальным с не меньшим уникальным подстроком внутри, так что это был бы ключ-кандидат. Это был бы единственный, поэтому это был бы первичный ключ.

Если ID_modulo однозначно определяет модуль только для каждой системы, то (ID_modulo,ID_sistema) был бы уникальным с не меньшим уникальным подстроком (при условии, что может быть более одной системы), так что это был бы ключ-кандидат. Это был бы единственный, поэтому это был бы первичный ключ.

Итак, какие ключи-кандидаты доступны для выбора в качестве первичного ключа, зависит от того, как ваше приложение ссылается на modulos. После этого нет выбора в отношении ключей-кандидатов. В каждом из этих двух случаев существует только один ключ-кандидат, поэтому выбора в отношении первичного ключа также нет.

Что касается того, должны ли вы иметь уникальный идентификатор в целом или только в системе, или оба, или что-то еще, это зависит от других эргономических проблем. Например, вы являетесь уникальным kentverger в stackoverflow (сейчас; имена пользователей не обязательно уникальны), но, возможно, уникальным Kent у себя дома. Например, вы, вероятно, предпочитаете называть сегодняшний день чем-то вроде 4 июля, а не 185-м днем. Но обратите внимание, что любой ключ-кандидат служит уникальным идентификатором. Таким образом, если ID_modulo уникален только внутри sistema, все равно (ID_modula, ID_sistema) уникален в целом.

Обратите внимание, что это не имеет ничего общего с тем, что модули являются много-к-одному с системами как таковыми. Это связано со столбцами, образующими уникальные подстроки.

Ответ №2:

Я всегда предпочитаю использовать идентификатор (автоинкремент) для первичного ключа, поскольку это позволяет лучше кластеризировать страницы и избежать фрагментации на диске. Вам в любом случае нужен внешний ключ ID_sistema, так что добавьте и это.

Комментарии:

1. Postgres не имеет кластеризованных индексов — и кластеризация с помощью PK в любом случае не всегда является таким хорошим выбором