2010-04-19 2 views
19

Почему отказ от составных ключей в пользу всех таблиц с использованием одного первичного ключа с именем id? Потому что вообще все ORM следуют этому.Почему единственный первичный ключ лучше составных?

EDIT

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

EDIT2 Также проверьте эту ссылку. Я получаю все больше и больше запутывается об этой вещи: --- Composite primary keys versus unique object ID field

Из приведенной выше ссылке: -

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

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

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

EDIT: есть дополнительная проблема, более практичная, чем философская. Во многих случаях вы каким-то образом найдете определенную строку, затем позже обновите ее или снова найдете (или и то, и другое). С составными ключами есть больше данных, чтобы отслеживать и больше ограничений в предложении WHERE для повторного поиска или обновления (или удаления). Также возможно, что один из ключевых сегментов может измениться за это время !. С суррогатный ключ, всегда существует только одно значение, чтобы сохранить (суррогатной ID) и по определению, он не может изменить, что значительно упрощает ситуацию. *

+3

Не могли бы вы привести источники? Я использую как: составные клавиши, так и первичные ключи идентификатора на основе последовательностей. Иногда один из них более уместен, чем другой. – FrustratedWithFormsDesigner

+0

Какой ORM вы используете, кто сторонники всегда используют простые клавиши над составными клавишами? Я никогда не сталкивался с ORM, который не играл хорошо с составными клавишами. Насколько я знаю, нет веских оснований для того, чтобы дать, например, стол соединения - суррогатный ключ. –

+0

@FrustratedWithFormsDesigner @Iain Galloway Я читал это, изучая Доктрину, и теперь я столкнулся с тем же, изучая Ruby на рельсах. Дайте мне знать, если вы хотите точный номер страницы книги, где написана эта строка. Я начинаю, поэтому я спрашиваю о реальной вещи. Не перекрестный вопрос или обсуждение этого. Означает, почему они используют это поле идентификатора. ?? –

ответ

21

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

Большинство людей используют суррогатный первичный ключ в качестве автоматического генерации int, поскольку он изолирует первичный ключ от когда-либо нуждающегося в изменении, например, если вы сделаете имя пользователя PK, а позже изменили свое юридическое имя. Вам нужно будет обновить PK и все столбцы FK, чтобы отобразить новое имя. если вы использовали суррогатный первичный ключ, вы просто обновляете имя пользователя в одном месте (потому что таблицы соединяются в int не с именем).

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

Имея автоинкремент int PK, он хорошо зарекомендовал себя как кластеризованный индекс, так как строки хранятся в этом порядке, и нет необходимости возвращаться назад и ударять строки из вставки новой строки, вы всегда добавляете к концу стола.

+0

Последовательные команды работают очень хорошо, особенно если вам нужно объединить наборы данных из нескольких баз данных в одну таблицу. – Juliet

+0

@Juliet, но они большие и ненужные индексные пространства. Если возможно, лучше всего комбинировать идентификатор int int int с другим столбцом с идентификацией базы данных/компании/etc (например, 1 или 2 байта int), откуда эта строка появилась из-за того, что она может использовать гораздо меньше места, чем руководство, но все же быть уникальным во всех базах данных. –

+4

Я бы не рекомендовал использовать гиды, кроме случаев с краями –

1
  1. Для ОРМ единой идентификации колонки с Такое согласованное имя, как table_id проще, чем составной ключ. Но каждая хорошая поддержка ORM составные клавиши.

  2. Простой PK может быть легко 'autoincremented' от базы данных. Это не относится к составной клавише .

  3. Простой PK также проще в использовании в запросах. Когда вам нужно присоединиться, вам необходимо использовать только один столбец из .

Это не означает, что простые PK лучше, чем композитные.

7

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

Как правило, я использую созданные идентификаторы для сущностей и составных ключей для отношений.

+0

Это тот же подход, который я использую, и он работает достаточно хорошо. –

0

Объекты программирования OO имеют личность независимо от их содержимого. Строки (кортежи) в реляционных базах данных определяются только их содержимым. Поэтому, когда вы действительно делаете ORM, то есть отображаете объекты с объектно-ориентированного языка программирования в реляционную базу данных, должен быть предоставлен дополнительный идентификатор, отличный от полей и/или свойств, которые объект имеет в программе, - если только один или несколько из них как-то известно, идентифицировать объекты однозначно.

+0

Вы, конечно же, нуждаетесь в * первичном ключе * на своем столе, но нет причин, по которым это должно быть один столбец. Композитные первичные ключи очень распространены, особенно на таблицах соединений. –

+0

Пожалуйста, прочитайте еще раз. Я не сказал, что первичные ключи требуются в схемах реляционных баз данных (они не являются), а также что составные ключи не возникают при разработке схем реляционных баз данных (они это делают). Я просто хотел сказать, что если ваша модель реляционной базы данных слепо * сгенерирована * из модели класса OO, все таблицы должны иметь суррогатные идентификаторы в качестве их первичных ключей, которые не соответствуют ни одному из свойств классов объектов. Таблицы соединений не будут генерироваться, если вы не будете рассматривать свойства, связанные с коллекцией, особым образом. – reinierpost

+0

Есть ли у вас особый способ представления отношения m: m без использования таблиц соединений? –

4

Ну, это в основном о сохранении JOIN и просто - какой из них проще понять:

SELECT 
    p.ID, p.Name, p.City, 
    c.ID, c.Country, c.ISOCode 
FROM 
    dbo.Parent p 
INNER JOIN 
    dbo.Child c on c.ParentID = p.ID 

или

SELECT 
    p.ID, p.Name, p.City, 
    c.ID, c.Country, c.ISOCode 
FROM 
    dbo.Parent p 
INNER JOIN 
    dbo.Child c ON c.ParentName = p.Name 
    AND c.ParentCity = p.City 
    AND c.ParentCountry = p.Country 

Если у вас есть составные первичные ключи, кто присоединиться к вашему столу от ребенка таблица должна «перетащить» все эти столбцы, и все эти столбцы также будут присутствовать в дочерней таблице, а операторы JOIN довольно беспорядочны. Гораздо лучше иметь один (даже суррогатный) ключ для JOIN!

+0

Вы бы рекомендовали использовать суррогатный ключ (а не сложный ключ) в качестве ПК для таблицы соединений, представляющей собой много-много отношений? Если да, то почему? –

+0

@Iain Galloway: необязательно - таблицы соединений для отношений «многие ко многим» - один из исключительных случаев, когда вы, вероятно, используете композитный ПК в своих интересах. Но нет никакого вреда (кроме дополнительных столбцов) при добавлении суррогатной ПК даже в этом случае - это позволит вам более легко управлять (например, удалять) записи из этой таблицы соединений. –

12

Единственное реальное ограничение, с которым я столкнулся, используя составные ключи, используя выражение IN с подзапросом. Это проблема, потому что подзапрос в выражении IN должен возвращать один столбец (по крайней мере, в T-SQL).

SELECT 
    emp.Name, 
    emp.UserDomain, 
    emp.UserID 
FROM 
    employee emp 
WHERE 
    ???? IN (SELECT e.UserDomain, e.UserID FROM ... /* some complex 
                 non-correlated subquery 
                 or CTE */ 
      ) 

Всегда есть обходные пути, но иногда это может быть неприятно.

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

0

Ваш вопрос сильно связан с альтернативой surrogate (or artificial) keys vs natural keys. Я думаю, что дело не в том, что составные ключи менее используются, но что натуральный ключей (будь то композитный или простой) менее предпочтительны, чем искусственный ключей.

Традиционная теория реляционной базы данных в основном используется с «естественными» ключами (те, которые имеют смысл с точки зрения бизнес-точки), и в этом случае составные ключи часто встречаются ... естественно.

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

+1

Композитные клавиши все еще находятся «естественно» при использовании суррогатных ключей , Суррогат против естественных ключей - это совершенно отдельная дискуссия! –

+0

Задать вопрос: «Почему отказ от составных ключей в пользу всех таблиц с использованием одного первичного ключа с именем id». «Единственный первичный ключ с именем id» - это как раз суррогатный ключ. – leonbloy

+1

Я внимательно прочитал вопрос. Он вообще не упоминает натуральные ключи. Дебаты (естественные и суррогатные и простые против композита) полностью разделены. Композитные клавиши часто возникают при отсутствии естественных клавиш. В соответствующем примере см., Например, http://megocode3.wordpress.com/2008/01/04/understanding-a-sql-junction-table/ Можете ли вы придумать вескую причину, чтобы дать этому перекрестному столбу собственный суррогатный ключ? –

2

Я работал над приложением с первичным ключом 11 столбцов. Всегда было весело переписывать список много раз, каждый раз, когда я хотел гарантировать, что я обновляю одну строку. Это был драйвер ошибок, MS-Access не смог справиться с более чем 10 столбцами в ПК и т. Д.

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

0

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

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

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

Смежные вопросы