如何根据移位创建一个 int 主键
How make an int primary key based on bit shift
我在 sql 服务器和 VB.net 上工作
我经常在 int 主键上使用 identity(1,1)。
但是今天我想创建一个 table 来替换枚举。我在我的程序中使用它,就像标记可以添加的东西(这是一个关于疾病的枚举,在我管理很少的疾病之前你可以有几种疾病......但现在我希望能够添加更多的疾病。)
我可以在我的 vb 代码中做到这一点,但我更喜欢我的 SQL 服务器单独处理他的密钥。但我找不到办法说 next key = last key << 1???
感谢您的帮助。
SQL 服务器没有位移运算符。
对于低至 15 条记录,我建议仅使用 tinyint
作为主键,并在输入下一行时手动输入值。
您可以让 SQL 服务器自动为您计算它,但要正确地计算它就太过分了。
一个天真的方法会是这样的:
CREATE TABLE disease
(
ident tinyint identity(1,1),
name varchar(100),
id AS (POWER(2, ident)) PERSISTED PRIMARY KEY
)
测试:
INSERT INTO disease (name) VALUES
('flu'), ('diabetes'), ('tonsillitis')
SELECT id, name
FROM disease
结果:
id name
2 flu
4 diabetes
8 tonsillitis
但这很天真,因为它假定标识列中没有间隙。 SQL服务器根本不保证。
为了正确地做到这一点你必须使用用户定义的函数来计算 id 列,该函数将实际计算在当前记录之前输入的记录数,然后return 2 的次方乘以该数字。
请注意,在这种情况下,您无法保留计算列,因此它不能成为主键。
CREATE TABLE disease
(
ident tinyint identity(1,1) PRIMARY KEY,
name varchar(100),
);
GO
CREATE FUNCTION fn_CalculateDiseaseId
(
@ident tinyint
)
returns smallint
AS
BEGIN
RETURN
POWER(2,
(
SELECT COUNT(*)
FROM disease
WHERE ident < @ident
) +1
)
END;
GO
ALTER TABLE disease
ADD id AS dbo.fn_CalculateDiseaseId(ident);
GO
与之前相同的测试:
INSERT INTO disease (name) VALUES
('flu'), ('diabetes'), ('tonsillitis')
SELECT id, name
FROM disease
结果:
id name
2 flu
4 diabetes
8 tonsillitis
我在 sql 服务器和 VB.net 上工作 我经常在 int 主键上使用 identity(1,1)。 但是今天我想创建一个 table 来替换枚举。我在我的程序中使用它,就像标记可以添加的东西(这是一个关于疾病的枚举,在我管理很少的疾病之前你可以有几种疾病......但现在我希望能够添加更多的疾病。)
我可以在我的 vb 代码中做到这一点,但我更喜欢我的 SQL 服务器单独处理他的密钥。但我找不到办法说 next key = last key << 1???
感谢您的帮助。
SQL 服务器没有位移运算符。
对于低至 15 条记录,我建议仅使用 tinyint
作为主键,并在输入下一行时手动输入值。
您可以让 SQL 服务器自动为您计算它,但要正确地计算它就太过分了。
一个天真的方法会是这样的:
CREATE TABLE disease
(
ident tinyint identity(1,1),
name varchar(100),
id AS (POWER(2, ident)) PERSISTED PRIMARY KEY
)
测试:
INSERT INTO disease (name) VALUES
('flu'), ('diabetes'), ('tonsillitis')
SELECT id, name
FROM disease
结果:
id name
2 flu
4 diabetes
8 tonsillitis
但这很天真,因为它假定标识列中没有间隙。 SQL服务器根本不保证。
为了正确地做到这一点你必须使用用户定义的函数来计算 id 列,该函数将实际计算在当前记录之前输入的记录数,然后return 2 的次方乘以该数字。
请注意,在这种情况下,您无法保留计算列,因此它不能成为主键。
CREATE TABLE disease
(
ident tinyint identity(1,1) PRIMARY KEY,
name varchar(100),
);
GO
CREATE FUNCTION fn_CalculateDiseaseId
(
@ident tinyint
)
returns smallint
AS
BEGIN
RETURN
POWER(2,
(
SELECT COUNT(*)
FROM disease
WHERE ident < @ident
) +1
)
END;
GO
ALTER TABLE disease
ADD id AS dbo.fn_CalculateDiseaseId(ident);
GO
与之前相同的测试:
INSERT INTO disease (name) VALUES
('flu'), ('diabetes'), ('tonsillitis')
SELECT id, name
FROM disease
结果:
id name
2 flu
4 diabetes
8 tonsillitis