У меня есть список объектов, каждый из которых имеет свой собственный идентификатор, и мне нужно создать для них таблицу в базе данных. Рекомендуется использовать их идентификаторы (поскольку они уникальны) в качестве первичного ключа в таблице, но есть одна проблема. Все идентификаторы являются целыми числами, за исключением одного объекта - у него есть 2 подобъекта с идентификаторами 142.1
и 142.2
, поэтому список идентификаторов равен 140, 141, 142.1, 142.2, 143...
Теперь, если я выберу двойной тип первичного ключа, он будет хранить ненужные 6 байтов (поскольку двойной равен 8 байты, а INT
равно 2) для поддержки только двух двойных чисел, и я не могу выбрать INT
. Итак, какой тип мне следует использовать, если я не могу изменить список объектов?
SQLServer выбирает тип первичного ключа
Ответы (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)
int
составляет четыре байта, а не два, поэтому разница в размере с двойным не так велика.
Однако вам определенно не следует использовать число с плавающей запятой в качестве ключа, поскольку число с плавающей запятой хранится не как точное значение, а как приближение.
Вы можете использовать decimal
с одной дробной цифрой, например decimal(5,1)
, для хранения такого значения. decimal
— это число с фиксированной точкой, поэтому оно хранится как точное значение, а не как приближенное.
Выберите 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]'
)
);
int
— это 4 байта, а не 2. (хотяsmallint
— это 2) - person Martin Smith   schedule 17.09.2011decimal(9,1)
составляет 5 байт - person Martin Smith   schedule 17.09.2011