Пользовательское поколение PrimaryKey с автоинкрементом - PullRequest
0 голосов
/ 03 декабря 2010

Мой вопрос такой же, как этот: Генерация пользовательского PrimaryKey с автоинкрементом .Но с небольшой неожиданностью.

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

У меня есть одна таблица с именем Customer, и она выглядит так:

alt text

IDэто ПК, а также установлен автоматический прирост.Все работало хорошо, пока я не решил запустить две компании в одной БД.После того, как я решил это, я добавил столбец с именем CompanyID, чтобы присоединить этого клиента к определенной компании.Это также работает, как и должно, когда я захожу в свою систему как пользователь компании 1, я получаю клиентов Compny 1 и т. Д.

Но проблемы появляются, когда я добавляю нового клиента в базу данных.Я хочу, чтобы идентификаторы клиентов начинались с 1 в обеих компаниях.Но, как и сейчас, когда я создаю клиента в компании 1, он получает клиента 1, а когда я создаю нового клиента в компании 2, он увеличивается на то же число, поэтому он получает клиента 2. Здесь я хотел, чтобы он былномер клиента 1. Два шага должны быть разделены на основе CompanyID.

. Первым шагом может быть добавление ID и CompanyID в качестве PK, но что еще я должен сделать для достижения этой цели?

Кроме того, если у вас есть другое мнение о том, как мне решить эту проблему, я хотел бы знать!

Ответы [ 2 ]

1 голос
/ 03 декабря 2010

Хорошо, во-первых, вам определенно необходимо определить свой PK как для CompanyID, так и для ID, если вы собираетесь выполнить эту задачу (в противном случае вы получите конфликт PK, когда попытаетесь вставить клиента 1 компании 2, предполагая, чтоУ компании 1 уже есть клиент 1.

Как только у вас возникнет требование «без пропусков», вам, скорее всего, придется что-то делать самостоятельно, а не использовать функции IDENTITY в SQL Server, и вы собираетесьпотеря масштабируемости.

Два очевидных варианта - выбрать MAX (ID) + 1 из этой таблицы для следующего идентификатора (но в этом случае необходимо поддерживать исключительную блокировку таблицы между определением этого значения и выполнением вставки.), Или для поддержки отдельной таблицы следующих идентификаторов, которые будут использоваться (в этом случае вам понадобится исключительная блокировка строки для строки, которую вы используете и увеличиваете). Например, у вас может быть такая таблица:

CREATE TABLE CompanyCustomerIDs (
    CompanyID int not null,
    NextCustomerID int not null,
    constraint PK_CompanyCustomerIDs PRIMARY KEY (CompanyID)
)

Тогда ваша вставка в таблицу «Клиенты» будет выглядеть примерно так:

declare @CustomerID int

begin transaction

update CompanyCustomerIDs WITH (ROWLOCK,HOLDLOCK,XLOCK) set @CustomerID = NextCustomerID = NextCustomerID + 1 where CompanyID = @CompanyID

insert into Customers (CompanyID,CustomerID,/* Other COlumns */)
select @CompanyID,@CustomerID,/* Other columns */

commit

Как я уже сказал, это будетоказывает влияние на масштабируемость базы данных.

1 голос
/ 03 декабря 2010

Лучший способ сделать это - иметь таблицу Company, которая позаботится о назначении своих собственных первичных ключей, и установить отношение внешнего ключа между Company.CompanyID и Customer.CompanyID. Затем сохраните информацию о компании в таблице Company, а данные о клиенте компании в таблице Customer. Это основное использование СУБД, такой как SQL Server, которая предназначена для хранения данных реляционным способом для эффективного управления данными.

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