Вопрос

Мне просто интересно, каково здесь оптимальное решение.

Допустим, у меня есть нормализованная база данных.Первичным ключом всей системы является varchar.Что мне интересно, так это должен ли я связать этот varchar с int для нормализации или оставить его?Проще оставить как varchar, но это может быть более оптимальным

Например, я могу иметь

People
======================
name      varchar(10)   
DoB       DateTime    
Height    int  

Phone_Number
======================
name      varchar(10)   
number    varchar(15)

Или я мог бы

People
======================
id        int Identity   
name      varchar(10)   
DoB       DateTime  
Height    int  

Phone_Number
======================
id        int   
number    varchar(15)  

Конечно, добавьте несколько других отношений "один ко многим".

Что вы все думаете?Что лучше и почему?

Это было полезно?

Решение

Вы действительно можете использовать имена в качестве первичных ключей?Разве не высок риск, что несколько человек с одним и тем же именем?

Если вам действительно так повезло, что ваш атрибут name можно использовать в качестве первичного ключа, то - во что бы то ни стало - используйте это.Однако часто вам придется что-то придумать, например, customer_id и т.д.

И, наконец,:"NAME" - это зарезервированное слово по крайней мере в одной СУБД, поэтому подумайте об использовании чего-нибудь другого, напримерполное имя.

Другие советы

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

Любой запрос разумного размера, который должен выполнять соединения между таблицами, использующими несурогатные ключи, где некоторые таблицы имеют составные первичные ключи, быстро становится недоступным для поддержки.

Использование любых несинтетических данных (т. е.что-либо от пользователя, в отличие от сгенерированного приложением) в качестве PK является проблематичным;вы должны беспокоиться о различиях в культуре / локализации, чувствительности к регистру (и других проблемах, зависящих от сортировки базы данных), которые могут привести к проблемам с данными, если / когда введенные пользователем данные когда-либо изменятся, и т.д.

Использование данных, не сгенерированных пользователем (последовательных идентификаторов GUID (или непоследовательных, если ваша база данных их не поддерживает или вас не волнует разделение страниц) или идентификаторов identity ints (если вам не нужны идентификаторы GUID)), намного проще и безопаснее.

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

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

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

Более того, текстовые данные - это настоящая пытка с точки зрения сравнений, ваша жизнь намного упрощается, когда вы делаете ГДЕ id = user_id пользователя против ГДЕ name ПОХОЖЕ НА inputname (или что-то подобное).

Если поле "имя" действительно подходит в качестве первичного ключа, то сделайте это.База данных будет нет получите больше нормализации, создав в этом случае суррогатный ключ.Вы получите несколько повторяющихся строк для внешних ключей, но это не проблема нормализации, поскольку ограничение FK гарантирует целостность строк так же, как и для суррогатных ключей.

Однако вы не объясняете, что это за "имя".На практике очень редко строка подходит в качестве первичного ключа.Если это имя человека, оно не будет работать как PK, поскольку одно и то же имя может быть у нескольких человек, люди могут менять имена и так далее.

Одна вещь, о которой другие, похоже, не упоминали, заключается в том, что соединения в полях int, как правило, выполняются лучше, чем соединения в полях varchar.

И я определенно всегда использовал бы суррогатный ключ вместо имен (людей или компаний), потому что они никогда не бывают уникальными с течением времени.Например, в нашей базе данных у нас есть 164 имени с более чем 100 экземплярами одного и того же имени.Это ясно показывает опасность использования name в качестве ключевого поля.

Первоначальный вопрос не касается нормализации.Если у вас есть нормализованная база данных, как вы заявили, то вам не нужно изменять ее по соображениям нормализации.

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

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

Вопрос о том, действительно ли предоставленный естественный ключ работает как естественный ключ или нет, гораздо более важен.Проблема дубликатов в столбце "имя" - не единственная проблема.Существует также проблема того, что происходит, когда человек меняет свое имя.Эта проблема, вероятно, не возникает в приведенном вами примере, но она возникает во множестве других приложений баз данных.Примером может служить стенограмма всех курсов, пройденных студентом за четыре года.Женщина может выйти замуж и сменить фамилию в течение четырех лет, и теперь вы застряли.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top