2012-05-16 2 views
1

* Я новичок в этом, я мог бы (вероятно, будет?) Будет говорить некоторые jibberish сейчас и потом, не стесняйтесь исправлять меня;)Объединение двух таблиц, дублированные ключи

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

В настоящее время существуют некоторые проблемы с производительностью с использованием GUID в качестве первичного ключа (и поведение по умолчанию использования его в качестве кластерного индекса). Существует несколько альтернатив, например, использование NEWSEQUENTIALID() или добавление дополнительного столбца IDENTITY для обеспечения последовательного кластеризованного индекса.

Еще один человек удаляет GUID в первичных ключах (и индексах) вместе, предоставляя столбец уникальной идентификации по всему миру, внешний идентификатор/rowid. Это оставляет вас с меньшими таблицами. Конечно, есть 16-байтовый штраф за дополнительный столбец, но это быстро уменьшается в таблицах с несколькими FK. Больше вещей на страницах, приятные последовательные идентификаторы, меньшее пространство индекса, так что выиграть победу выиграть.

Этот подход, однако, оставляет нам неприятный недостаток: когда вы хотите объединить 2 таблицы, вы застреваете с дублирующимися ключами. Теперь я не сторонник этого подхода, я просто изучаю и сравниваю различные стратегии, чтобы сделать меня более разбирающимся в этой части дизайна базы данных.

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

ответ

4

Я не думаю, что вам нужно GUID вообще. Хотя NEWSEQUENTIALID() является лучшим вариантом, чем NEWID() с точки зрения разделения страниц, в большинстве случаев он по-прежнему является более широким ключом, чем необходимо, и вы проиграете единственное преимущество GUID (которое вы можете сгенерировать заранее), которое вы не может работать с NEWSEQUENTIALID()). Тем не менее у вас по-прежнему есть аналогичная проблема с горячими точками как значения IDENTITY, где все действия вставки происходят в одинаковой степени. Так что же вы на самом деле получили?

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


Идентичность Диапазоны

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

CREATE TABLE dbo.Data 
(
    ID BIGINT IDENTITY(1000000000, 1) PRIMARY KEY 
); 

На сервере два:

CREATE TABLE dbo.Data 
(
    ID BIGINT IDENTITY(2000000000, 1) PRIMARY KEY 
); 

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

Размер ключа: 8 байт.(или 4 байта еще, если вы можете использовать INT.)


Составной ключ

Другой подход заключается просто есть столбец идентификатор_сервера на столе, и сделать эту часть составной ключ. До тех пор, пока вы не планируете расширение за пределами 255 серверов, вы можете использовать TINYINT (1 байт). На сервере одного:

CREATE TABLE dbo.Data 
(
    ServerID TINYINT NOT NULL DEFAULT 1, 
    DataID INT IDENTITY(1,1), 
    PRIMARY KEY (ServerID, DataID) 
); 

На сервере два:

CREATE TABLE dbo.Data 
(
    ServerID TINYINT NOT NULL DEFAULT 2, 
    DataID INT IDENTITY(1,1), 
    PRIMARY KEY (ServerID, DataID) 
); 

Теперь вы просто должны нести обе колонки вокруг в ФКС на объединенном системе (или создать столбец IDENTITY в слиянии) .. немного более болезненным для объединений, но намного легче, чем носить с собой GUID.

Размер ключа: 5 байт.(или 6 байт, если вам нужно подойти к SMALLINT поскольку 255 серверов не хватает.)

+0

Спасибо за этот полезный пост, всегда приятно получить больше информации от других :) – fuaaark

0

Из любопытства, в чем цель слияния?

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

Это зависит от случая использования, но я, как правило, держаться подальше от GUIDs, если нет необходимости

+0

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

+0

Я сделал предположение, что FK указывали на другие столбцы, но хорошая точка :) – Charleh

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