SQLServer выбирает тип первичного ключа

У меня есть список объектов, каждый из которых имеет свой собственный идентификатор, и мне нужно создать для них таблицу в базе данных. Рекомендуется использовать их идентификаторы (поскольку они уникальны) в качестве первичного ключа в таблице, но есть одна проблема. Все идентификаторы являются целыми числами, за исключением одного объекта - у него есть 2 подобъекта с идентификаторами 142.1 и 142.2, поэтому список идентификаторов равен 140, 141, 142.1, 142.2, 143... Теперь, если я выберу двойной тип первичного ключа, он будет хранить ненужные 6 байтов (поскольку двойной равен 8 байты, а INT равно 2) для поддержки только двух двойных чисел, и я не могу выбрать INT. Итак, какой тип мне следует использовать, если я не могу изменить список объектов?


person Sergey    schedule 17.09.2011    source источник
comment
Не хорошая идея. Вы никогда не должны вкладывать логику в свои первичные ключи. Информацию о подобъектах следует вынести в отдельный столбец.   -  person a_horse_with_no_name    schedule 17.09.2011
comment
int — это 4 байта, а не 2. (хотя smallint — это 2)   -  person Martin Smith    schedule 17.09.2011
comment
Я знаю, но я не могу ничего изменить прямо сейчас, мне нужно решить эту проблему тем, что у меня есть.   -  person Sergey    schedule 17.09.2011
comment
Мартин, я просмотрел эту таблицу w3schools.com/sql/sql_datatypes.asp.   -  person Sergey    schedule 17.09.2011
comment
@Сергей - понятия не имею о точности этой таблицы, но в любом случае она предназначена для Microsoft Access, а не для SQL Server. Точную информацию см. в электронной документации, а не в w3schools. decimal(9,1) составляет 5 байт   -  person Martin Smith    schedule 17.09.2011
comment
@Сергей, на этом сайте написано 4 байта. вы, вероятно, смотрели на типы данных Access. Типы данных SQL Server почти внизу страницы.   -  person Icarus    schedule 17.09.2011
comment
Почему вас волнует количество байтов вашего ПК? Если это AccessDb, то чего вы боитесь? Даже если вы хотите хранить 2 000 000 строк, то есть всего 2 МБ места для дополнительного байта — любой компьютер может обработать гораздо больше.   -  person kubal5003    schedule 17.09.2011


Ответы (3)


Математика для double неточна, ее не следует использовать для дискретных чисел, таких как деньги или идентификаторы объектов. Вместо этого рассмотрите возможность использования decimal(p,s). Где p — общее количество цифр, а s — количество цифр после точки. Например, decimal(5,2) может хранить 123.45, но не 1234 или 12.345.

Другой вариант — составной первичный ключ для двух целых чисел n1, n2:

alter table YourTable add constraint PK_YourTable primary key (n1, n2)
person Andomar    schedule 17.09.2011

int составляет четыре байта, а не два, поэтому разница в размере с двойным не так велика.

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

Вы можете использовать decimal с одной дробной цифрой, например decimal(5,1), для хранения такого значения. decimal — это число с фиксированной точкой, поэтому оно хранится как точное значение, а не как приближенное.

person Guffa    schedule 17.09.2011

Выберите VARCHAR подходящей длины с ограничениями CHECK, чтобы данные соответствовали правилам вашего домена, например. на основе небольших выборочных данных, которые вы опубликовали:

CREATE TABLE Ids 
(
 id VARCHAR(5) NOT NULL UNIQUE
    CONSTRAINT id__pattern
       CHECK (
              id LIKE '[0-9][0-9][0-9]'
              OR id LIKE '[0-9][0-9][0-9].[1-9]'
             )
);
person onedaywhen    schedule 21.09.2011