#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 в любом случае не всегда является таким хорошим выбором