有没有办法在MySql中创建一个具有自动ID字段的表,但ID不是顺序的。例如,随机或伪随机ID。 我找到了建议生成ID并尝试插入ID的解决方案,直到找到未使用的ID(generating an sequential five digit alphanumerical ID)。 但是没有什么可以直接在表定义中完成,或者更简单的技巧。
答案 0 :(得分:11)
MySQL有一个本机函数UUID()
,它将生成一个全局唯一标识符:
mysql> SELECT UUID();
-> '6ccd780c-baba-1026-9564-0040f4311e29'
您可以将其输出存储在CHAR(36)
列中。
INSERT INTO table (`uuid`, `col1`, `col2`) VALUES (UUID(), 'someval', 'someval');
根据文件,
虽然UUID()值是唯一的,但它们不一定是不可取的或不可预测的。如果需要不可预测性,则应以其他方式生成UUID值。
附录对于64位unsigned INT
而非字符字段,另一个选项是UUID_SHORT()
。
mysql> SELECT UUID_SHORT();
-> 92395783831158784
答案 1 :(得分:3)
既然你要求一个技巧,你可以使用一个常见的auto_incremented id并通过乘以一个大素数来“假”它(然后模2 ^ 32):
CREATE TABLE AutoIncPrime
(id int unsigned auto_increment primary key
) ;
插入值,从1到10:
INSERT INTO AutoIncPrime
VALUES (),(),(),(),(),(),(),(),(),() ;
SELECT * FROM AutoIncPrime ;
输出:
id
---
1
2
3
4
5
6
7
8
9
10
使用View:
伪造id
CREATE VIEW AutoIncPrime_v AS
SELECT
((id*1798672429 ) & 0xFFFFFFFF)
AS FakeUUID
FROM AutoIncPrime ;
让我们看看我们的“UUIDs”:
SELECT * FROM AutoIncPrime_v ;
输出:
FakeUUID
----------
1798672429
3597344858
1101049991
2899722420
403427553
2202099982
4000772411
1504477544
3303149973
806855106
你甚至可以让它看起来更随机(更复杂的比特混合):
CREATE VIEW AutoIncPrime_v2 AS
SELECT
( (((id*1798672429 ) & 0x55555555) << 1)
| (((id*1798672429 ) & 0xAAAAAAAA) >> 1)
)
AS FakeUUID
FROM AutoIncPrime ;
SELECT * FROM AutoIncPrime_v2 ;
FakeUUID
----------
2537185310
3918991525
2186309707
1558806648
604496082
1132630541
3719950903
2791064212
3369149034
808145601
技巧是你在表中仍然有一个顺序id - 你可以用它来连接到其他表。你只是不向用户展示它 - 但只显示假的。
如果要增大表并且计算速度慢,可以在表中添加另一列,并使用INSERT触发器存储FakeUUID值。
答案 2 :(得分:2)
复合键是否有效?常规标准auto_increment字段。您插入新记录,检索其新ID,然后使用salt哈希该ID,并使用该哈希值更新记录。
如果您在事务中执行此操作,则在生成哈希之前,不会显示没有哈希的记录的正在进行版本。假设您已经完成了正确的盐析,则生成的哈希值将用于所有意图和目的“随机”。
请注意,您无法在一个步骤中执行此操作,因为在实际写入记录之前,mysql中的last_insert_id()值未使用新ID更新。在实际插入解析阶段期间检索的值将是在此之前插入的任何ID。
答案 3 :(得分:1)
允许的表定义中唯一自动生成的默认值为autoincrement(MySQL Guide)。
您应该能够write a trigger自动执行此过程,可能是通过Michael建议的UUID功能。