Использование auto_increments для объединения таблиц MyISAM в MySQL - PullRequest
0 голосов
/ 25 января 2010

Пока я писал php в течение долгого времени, я всегда учился этому навыку, и я только что столкнулся с небольшим кризисом уверенности по поводу объединения таблиц!

Предполагается, что MySQL db auth содержит таблицы MyISAM users и permissions:

users
- id (auto increment)
- email

permissions
- id (auto increment)
- name

Чтобы объединить эти таблицы во многие-ко-многим (или один-ко-многим), я всегда использовал таблицы-мосты, например:

user_permissions
- id (auto increment)
- user_id
- permission_id

(я знаю, что innoDB способен к отношениям, но он также более сложен и требует больше памяти, поэтому для цели я хотел бы остаться с myISAM)

Мой конкретный вопрос заключается в следующем: целесообразно ли объединять таблицы с помощью автоинкрементного ключа или мне нужно создать собственный дополнительный ключ?

Я знаю, что могут возникнуть проблемы, если таблица будет повреждена, и мне придется перестраивать ее или если я начну зеркалировать до двух БД, и ключи будут не синхронизированы.

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

Как все это делают? Эти проблемы вы видели в практических ситуациях?

Спасибо за ваше время!

Адам

Ответы [ 2 ]

0 голосов
/ 25 января 2010

Как правило, это решение между использованием суррогатных ключей (скомпонованных или автоматически назначенных значений, которые не имеют смысла, кроме того, что они уникальны), и естественными ключами (ключами, которые имеют некоторое семантическое значение в отношении сохраняемой сущности, например, имени или банковский счет #).

в вашем случае неясно, есть ли какой-нибудь естественный ключ, который будет работать (каждый аспект пользовательской таблицы может измениться - смена имени после вступления в брак и т. Д.). вам нужен естественный ключ, если нет возможности, чтобы ключ когда-либо изменялся, сохраняя при этом отношения. Примером может быть что-то вроде имен элементов (Au, He, Es и т. д.) в периодической таблице элементов (которые вряд ли изменятся, кроме добавления новых, но, эй, все может произойти ...).

Что касается повреждения данных, резервные копии действительно лучшая защита, потому что все может быть повреждено. и в типичных операциях вы всегда можете сохранить первичный ключ при миграции или синхронизации. использование сложного сложного суррогатного ключа вместо автоматического приращения, предоставляемого БД, было бы более рискованным, поскольку это усложняет вставки (вы должны обеспечить его уникальность и, возможно, обрабатывать коллизии безопасным способом транзакции) ... и действительно сгенерированным суррогатом Ключ не поможет в случае повреждения данных (нет способа сопоставить его с записью).

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

хорошая рецензия здесь:

http://decipherinfosys.wordpress.com/2007/02/01/surrogate-keys-vs-natural-keys-for-primary-key/

0 голосов
/ 25 января 2010

Объединение для разрешения и пользователей будет выглядеть так:

SELECT      u.*, p.*
FROM        user_permissions up
INNER JOIN  users            u
ON          up.user_id = u.id
INNER JOIN  permissions      p
ON          up.permission_id = p.id

Столбец id в user_permission на самом деле не нужен, если только вы не хотите сослаться на это из другой таблицы. Если вы укажете этот идентификатор, (user_id, license_id) будет первичным ключом (в этом случае автоматическое увеличение не происходит). Если у вас есть отдельный столбец идентификатора, то вам обязательно нужно добавить ограничение UNIQUE поверх (user_id, license_id)

...