10

我有一张表,名为events所有新信息的去向。此表用作所有新闻提要查询的参考,因此从那里选择事件项,并从正确的表中检索与该事件对应的信息。

现在,这是我的问题。我E_ID在事件表中有 's 对应于不同表中事件的 ID,无论是T_IDfor tracksS_IDforstatus等等......这些 ID 可能是相同的,所以暂时我只是使用了不同的 auto_increment 值对于每个表,因此status从 0 上的 500tracks等开始。显然,我不想这样做,因为我还不知道哪个表中的数据最多。我认为status会很快超过tracks.

event信息通过触发器插入到表中。这是一个例子;

BEGIN
INSERT INTO events (action, E_ID, ID)
VALUES ('has some news.', NEW.S_ID, NEW.ID);
END

那是他的状态表。

是否可以添加该触发器以确保NEW.S_ID!=E_ID当前在events其中,如果它确实会S_ID相应地更改。

或者,当自动递增时,是否有某种键可以用来引用事件,S_ID以便S_ID不会递增到E_ID.

这些是我的想法,我认为后一种解决方案会更好,但我怀疑这是可能的,或者它是可能的,但需要另一个参考表并且太复杂。

4

3 回答 3

15

要求跨表使用唯一 id 确实很少见,但这里有一个解决方案可以做到这一点。

/* Create a single table to store unique IDs */
CREATE TABLE object_ids (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    object_type ENUM('event', ...) NOT NULL
) ENGINE=InnoDB;

/* Independent object tables do not auto-increment, and have a FK to the object_ids table */
CREATE TABLE events (
    id INT UNSIGNED NOT NULL PRIMARY KEY,
    ...
    CONSTRAINT FOREIGN KEY (id) REFERENCES object_ids (id)
) ENGINE=InnoDB;

/* When creating a new record, first insert your object type into the object_ids table */
INSERT INTO object_ids(object_type) VALUES ('event');
/* Then, get the auto-increment id. */
SET @id = LAST_INSERT_ID();
/* And finally, create your object record. */
INSERT INTO events (id, ...) VALUES (@id, ...);

显然,您会events为其他表复制表的结构。

于 2013-06-06T12:20:48.540 回答
3

您也可以只使用通用唯一标识符 (UUID)。

UUID 被设计为在空间和时间上全球唯一的数字。对 UUID() 的两次调用预计会生成两个不同的值,即使这些调用是在未相互连接的两台独立计算机上执行的。

请在手册中阅读有关它的更多信息

还有一个较短的版本

于 2013-06-06T13:17:19.953 回答
1

UUID_SHORT()应该做的伎俩。它将为您生成 64 位无符号整数。

根据文档,生成器逻辑是:

(server_id & 255) << 56
+ (server_startup_time_in_seconds << 24)
+ incremented_variable++;

如果满足以下条件,则保证 UUID_SHORT() 的值是唯一的:

  • 当前服务器的 server_id 值在 0 到 255 之间,并且在您的主从服务器集合中是唯一的

  • 您不会在 mysqld 重新启动之间设置服务器主机的系统时间

  • 您在 mysqld 重新启动之间平均每秒调用 UUID_SHORT() 少于 1600 万次

mysql> SELECT UUID_SHORT();
    -> 92395783831158784

如果您好奇您的服务器 ID 是什么,您可以使用以下任何一种:

SELECT @@server_id
SHOW VARIABLES LIKE 'server_id';
于 2018-01-06T00:00:30.930 回答