Entity Framework Core自定义主键:如何生成10位随机非自增主键?
10位随机数字主键的实现方案
针对已创建的数据表,替换自增主键为10位随机数字主键,以下是主流数据库的具体实现方法:
MySQL 实现
1. 调整现有表结构
如果原主键是自增类型,先移除自增属性并调整字段类型(10位数字用BIGINT足够容纳,范围覆盖1000000000到9999999999):
-- 移除自增属性并修改字段类型 ALTER TABLE your_table MODIFY COLUMN id BIGINT NOT NULL; -- 确保主键约束生效(若原主键已存在可省略此步) ALTER TABLE your_table ADD PRIMARY KEY (id);
2. 生成唯一10位随机主键
直接插入时生成
利用RAND()函数生成指定范围的随机数:
INSERT INTO your_table (id, col1, col2) VALUES (FLOOR(1000000000 + RAND() * 9000000000), '示例值1', '示例值2');
存储过程保障唯一性
若担心重复,用存储过程循环生成直到得到未使用的ID:
DELIMITER // CREATE PROCEDURE get_unique_10digit_id(OUT new_id BIGINT) BEGIN DECLARE temp_id BIGINT; DECLARE exists_count INT; REPEAT SET temp_id = FLOOR(1000000000 + RAND() * 9000000000); SELECT COUNT(*) INTO exists_count FROM your_table WHERE id = temp_id; UNTIL exists_count = 0 END REPEAT; SET new_id = temp_id; END // DELIMITER ; -- 调用存储过程插入数据 CALL get_unique_10digit_id(@new_id); INSERT INTO your_table (id, col1) VALUES (@new_id, '测试数据');
PostgreSQL 实现
1. 调整表结构
先删除原自增序列,再修改主键字段属性:
-- 删除关联的自增序列(序列名通常为"表名_字段名_seq") DROP SEQUENCE IF EXISTS your_table_id_seq; -- 移除字段默认值并确保非空 ALTER TABLE your_table ALTER COLUMN id SET NOT NULL; ALTER TABLE your_table ALTER COLUMN id DROP DEFAULT;
2. 生成唯一10位随机主键
直接插入时生成
用random()函数生成范围值:
INSERT INTO your_table (id, col1) VALUES (FLOOR(1000000000 + random() * 9000000000)::BIGINT, '示例值');
自定义函数保障唯一性
创建函数循环生成唯一ID:
CREATE OR REPLACE FUNCTION generate_unique_10digit_id() RETURNS BIGINT AS $$ DECLARE temp_id BIGINT; BEGIN LOOP temp_id := FLOOR(1000000000 + random() * 9000000000)::BIGINT; EXIT WHEN NOT EXISTS (SELECT 1 FROM your_table WHERE id = temp_id); RETURN temp_id; END LOOP; END; $$ LANGUAGE plpgsql; -- 使用函数插入数据 INSERT INTO your_table (id, col1) VALUES (generate_unique_10digit_id(), '测试数据');
SQL Server 实现
1. 调整表结构
SQL Server无法直接移除IDENTITY属性,需通过临时表重建:
-- 将数据导出到临时表 SELECT * INTO temp_your_table FROM your_table; -- 删除原表 DROP TABLE your_table; -- 重建表,设置主键为BIGINT类型(无自增) CREATE TABLE your_table ( id BIGINT NOT NULL PRIMARY KEY, col1 VARCHAR(50), -- 其他字段与原表保持一致 ); -- 将临时表数据导回 INSERT INTO your_table SELECT id, col1 FROM temp_your_table; -- 删除临时表 DROP TABLE temp_your_table;
2. 生成唯一10位随机主键
直接插入时生成
用RAND()函数生成范围值:
INSERT INTO your_table (id, col1) VALUES (FLOOR(1000000000 + RAND() * 9000000000), '示例值');
存储过程保障唯一性
创建存储过程生成唯一ID:
CREATE PROCEDURE GenerateUnique10DigitID @new_id BIGINT OUTPUT AS BEGIN DECLARE @temp_id BIGINT; DECLARE @exists_flag INT; WHILE 1=1 BEGIN SET @temp_id = FLOOR(1000000000 + RAND() * 9000000000); SELECT @exists_flag = COUNT(*) FROM your_table WHERE id = @temp_id; IF @exists_flag = 0 BEGIN SET @new_id = @temp_id; BREAK; END END END; -- 调用存储过程插入数据 DECLARE @id BIGINT; EXEC GenerateUnique10DigitID @id OUTPUT; INSERT INTO your_table (id, col1) VALUES (@id, '测试数据');
关键注意事项
- 唯一性:数据量较大时,直接生成随机数可能出现重复,建议用存储过程/函数循环校验,或预生成一批唯一ID存入临时表,插入时取数删除,提升性能。
- 字段类型:优先选
BIGINT,比CHAR(10)更适合索引和数字操作;若用字符类型需确保无空格等冗余字符。 - 性能:大表场景下,查询校验存在性能损耗,预生成ID池是更优方案。
内容的提问来源于stack exchange,提问作者Ramazan Musluoğlu
相关产品推荐
相关产品推荐

