Нужны ли суррогатные первичные ключи в таблице фактов в хранилище данных? - PullRequest
3 голосов
/ 30 мая 2009

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

Мне кажется, что каждая таблица в исходной системе должна иметь PK, даже если это столбец идентификаторов. Учитывая, что хранилище данных (DW) является получателем данных из другой системы, - как бы я мог гарантировать, что данные в DW точно отражают то, что находится в исходной системе, если нет способа связать отдельные записи? Если у вас есть прогоненная программа загрузки, которая запутывает данные и работает в течение недели, как бы вы согласовали различия с исходной системой транзакций без каких-либо уникальных ограничений для сравнения?

Ответы [ 12 ]

9 голосов
/ 30 мая 2009

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

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

Время не является обязательным измерением при построении таблиц хранилища данных.

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

3 голосов
/ 22 февраля 2013

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

В SQL Server столбец идентификаторов дает вам бесплатный суррогатный ключ, а в других системах, использующих последовательности (например, Oracle), его можно добавить довольно легко. Ключи суррогатной таблицы фактов могут быть полезны по разным причинам. Некоторые возможные приложения:

  • Некоторым инструментам нравится иметь числовые ключи в таблицах фактов, предпочтительно монотонно увеличивающиеся. Примером этого является MS SQL Server Analysis Services, которому действительно нравится иметь числовой монотонно увеличивающийся ключ для таблиц фактов, используемых для заполнения групп мер. Это особенно необходимо для дополнительных нагрузок.

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

  • Если у вас есть измерения, живущие в отношении M: M с таблицей фактов (например, кодами ICD), то числовой ключ в таблице фактов упрощает это.

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

  • Если вы выполняете операции противоположного пересчета в вашем хранилище данных (т. Е. Обрабатываете изменения в транзакционных данных путем генерации сторнирования и повторного определения строки), то вы можете иметь несколько строк таблицы фактов для одного и того же естественного ключа.

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

3 голосов
/ 30 мая 2009

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

2 голосов
/ 15 февраля 2012

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

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

Итак, первоначальный вопрос для меня: «Должен ли я иметь суррогатный первичный ключ в таблице фактов?» но больше похоже на "должен ли я иметь кластерный индекс в таблице фактов?" Я думаю, что ответ «да», у вас должен быть один (и да, на этом сайте есть другие посты, посвященные этому вопросу, но я все же думаю, что здесь стоит упомянуть на тот случай, если этот вопрос действительно задают люди, несмотря на неправильную формулировку)

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

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

Чтобы обойти это (и причину, по которой я отвечаю здесь), я думаю, что вы ДОЛЖНЫ добавить суррогат, а затем создать кластеризованный индекс для ключа даты, а затем суррогат (в таком порядке). Я делаю это, потому что сама дата не собирается делать уникальную строку, но добавление суррогатной воли. Это сохраняет данные, упорядоченные по дате, что помогает всем другим некластеризованным индексам, а также сохраняет разумный размер кластеризованного индекса.

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

2 голосов
/ 31 мая 2009

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

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

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

При разработке базы данных для использования в OLTP неразумно иметь таблицу без первичного ключа. Те же соображения не переносятся на склады.

2 голосов
/ 30 мая 2009

Я бы с тобой согласился.

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

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

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

2 голосов
/ 30 мая 2009

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

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

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

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

2 голосов
/ 30 мая 2009

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

0 голосов
/ 10 марта 2013

Здесь вы объединяете две проблемы - определение уникальной записи в таблице фактов и отслеживание записей из исходной системы до таблицы фактов.

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

На вопрос о первичном ключе в таблице фактов действительно нет «правильного» ответа. Существуют желательные / существенные характеристики, которые вам могут понадобиться (например, для идентификации одной записи, которая будет легко передаваться между пользователями системы, или для того, чтобы одна запись была легко удалена или обновлена) Однако для системы Oracle ROWID вполне может подойти для этого, если не имеет значения, изменится ли он время от времени.

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

0 голосов
/ 20 декабря 2012

Использование комбинации суррогатных ключей измерения в качестве первичного ключа таблицы фактов работает не во всех случаях. Рассмотрим случай, когда есть три измерения a, b и c. В большинстве проектов у нас обычно есть строка измерения для «неизвестного», предположим, что я всегда присваиваю этой строке суррогатный ключ -1. Я мог бы легко иметь две строки в моей таблице фактов, которые имеют ключи a = n1, b = n2 и c = -1, то есть дубликаты ключей, потому что две строки не получили действительные значения для измерения c, и поэтому обе разрешаются в неизвестную строку.

...