Совместно использовать автоинкрементный первичный ключ между двумя таблицами - PullRequest
9 голосов
/ 03 октября 2008

Привет, я хочу, чтобы в каждой таблице было столбец INT "id", который будет автоматически увеличиваться, но я не хочу, чтобы столбцы "id" когда-либо разделяли одно и то же число. Как это называется и как лучше это сделать? Последовательность? Итератор? Индекс? Инкрементор

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

Я использую SQL Server 9.0.3068.

Спасибо!

Ответы [ 9 ]

14 голосов
/ 03 октября 2008

Просто настройте приращение идентификатора на> 1, например. В первой таблице используется IDENTITY (1, 10) [1,11,21 ...], а во второй таблице используется IDENTITY (2, 10) [2,12,22 ...]. Это также даст вам некоторое пространство для расширения, если потребуется позже.

3 голосов
/ 03 октября 2008

Я думаю, что использование GUID было бы самым простым способом, если я вас правильно понял.

SELECT NEWID()
2 голосов
/ 03 октября 2008

Используйте столбец с типом GUID (глобальный уникальный идентификатор). Это 16 байт, и он всегда будет уникальным для каждой строки.

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

1 голос
/ 03 октября 2008

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

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

CREATE TABLE AlwaysRollback (
  id IDENTITY(1,1)
);

BEGIN TRANSACTION;
INSERT INTO AllwaysRollBack () VALUES ();
ROLLBACK TRANSACTION;

INSERT INTO RealTable1 (id, ...) VALUES (SCOPE_IDENTITY(), ...);

BEGIN TRANSACTION;
INSERT INTO AllwaysRollBack () VALUES ();
ROLLBACK TRANSACTION;

INSERT INTO RealTable2 (id, ...) VALUES (SCOPE_IDENTITY(), ...);
1 голос
/ 03 октября 2008

Используйте другую таблицу с ключом идентификатора типа int по умолчанию его значение 1, называемое KeyID или любым другим.

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

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

0 голосов
/ 18 июля 2016

Начиная с SQL Server 2012, вы можете объявить объект последовательности https://msdn.microsoft.com/en-us/library/ff878091.aspx это именно то, что вам нужно.

Мне должно быть довольно тривиально эмулировать объект последовательности с таблицей содержащий следующее значение последовательности и хранимую процедуру атомарно выберите значение и приращение. [Вы хотели бы использовать функцию, но функции не может иметь побочных эффектов.]

Как насчет этого хака? Создайте таблицу (MySequence) с двумя столбцами: столбец And Identity (SequenceValue) и фиктивный столбец (DummyValue) и используйте эту хранимую процедуру для получения нового значения последовательности. Единственной строкой в ​​таблице будет последнее полученное значение последовательности.

CREATE PROCEDURE GetNextValue 
AS
BEGIN
    DECLARE @value int = null;

    -- Insert statements for procedure here
    INSERT into MySequence (DummyValue) Values (null);

    SET @value = SCOPE_IDENTITY();

    DELETE from MySequence where SequenceValue <> @value

    SELECT @value as Sequence

    return @value
END

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

0 голосов
/ 19 января 2011

Если вам действительно нужно сделать это с помощью int, и у вас есть число с автоматическим приращением, то, как я делал это раньше, это изменить функцию автоматического увеличения поля id на последовательность другой таблицы. Я не слишком уверен в MS SQL или моем SQL, но в pgsql это означает, что в SQL вы бы имели это поле

 id integer NOT NULL DEFAULT nextval('table_two_seq'::regclass),

где table_two_sequence - функция последовательности для другой таблицы. Затем проверьте это, вставив некоторые данные. Я действительно извиняюсь, если это не будет работать в MS SQL, я стараюсь держаться подальше от этого. В противном случае, GUID является лучшим способом, как было упомянуто другими. Или при вставке в код, который вы используете, вы можете поместить в него алгоритм, но он может запутаться.

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

Надеюсь, я помог

0 голосов
/ 03 октября 2008

Я лично являюсь поклонником решения GUID, но здесь возможный вариант.

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

Если GUID не будет работать для вас, и вы обязательно должны иметь int, bigint и т. П., Вы всегда можете просто использовать столбец IDENTITY и иметь каждую таблицу с различным значением для SEED. Эти типы данных имеют очень широкий диапазон, и нетрудно разделить диапазон на пригодные для использования сегменты, особенно если вам нужно только два разделения. Например, basic int имеет диапазон от -2 ^ 31 (-2 147 483 648) до 2 31: 1 (2 147 483 647). Например, этого более чем достаточно для таблицы клиентов.

Справочник по Transact-SQL (SQL Server 2000) int, bigint, smallint и tinyint

Пример:

--Create table with a seed of 1 billion and an increment of 1
CREATE TABLE myTable
(
primaryKey int IDENTITY (1000000000, 1),
columnOne varchar(10) NOT NULL
)
0 голосов
/ 03 октября 2008

Я не знаю, как бы вы это назвали.

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

Затем можно вызвать эту функцию в триггере вставки в обеих таблицах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...