如何在SQL中实现多个表的全局递增id?
当我编码时,我决定为每种类型的内容使用不同的表格。现在我被困在解决这个问题上。基本上,我的通知系统当前按时间戳对最新内容进行排名。然而,这是不准确的,因为某人与另一个人同时提交内容的可能性很小,并且会出现不正确的排名。
现在,如果我将所有内容放在一个表中,我只需通过自动递增变量对其进行排名即可。有没有办法在多个表中实现这种自动递增整数(例如,当将某些内容插入table1,id=0时,将某些内容插入table2,id=1 )。或者我是否必须将所有内容重新编码到一个表中。
注意:
我在多个表中包含内容的原因是因为它是有组织的并且可以减少负载压力。我不再关心组织了,因为我可以通过我编码的 GUI 访问数据,我只是想知道负载压力。
编辑:
我正在使用 PHP 5 和 MySQL。
I decided back when I was coding to have different tables for each type of content. Now I am stuck solving this. Basically my notification system ranks the newest content by its timestamp currently. This is inaccurate however because there is a small chance that someone would submit content at the same time as another person, and incorrect ranking would occur.
Now if I had all my content in a single table, I would simply rank it by an auto-incrementing variable. Is there a way to implement this auto-increment integer across multiple tables (e.g. When something is inserted into table1, id=0, something is inserted into table2, id=1). Or do I have to recode all my stuff into a single table.
NOTE:
The reason I have content in multiple tables is because its organized and it would reduce load stress. I don't really care about the organization anymore, because I can just access the data through a GUI I coded, I'm just wondering about the load stress.
EDIT:
I'm using PHP 5 with MySQL.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的问题,特别是跨多个表的 ID 的需求,清楚地表明您的数据库设计需要更改。您应该为所有内容类型创建一张表(作为概括),并具有自动递增 ID。然后,对于每个特定的内容类型,您可以定义具有额外字段的其他表(相当于 OOP 中的继承)以及指向基本表的外键。
换句话说,您需要类似于SQL 中的继承 。
Your question, particularly the need for ID spanning over multiple tables, is clearly signalizing that your database design needs change. You should make one table for all content types (as a generalization), with autoincrementing ID. Then, for each particular content type, you can define other table (equivalent of inheritance in OOP) with extra fields, and foreign key pointing to the basic table.
In other words, you need something like inheritance in SQL.
您可以创建一个具有自动增量 ID 的表来跟踪 ID。您的程序将在该表上执行插入操作,获取 id,并根据需要使用它。
大致如下:
其中 seq_table 是您必须创建的表,只是为了获取 id。使其成为一个函数,以便在需要时可以使用它。每生成 10 个 id,我就会删除所有生成的 id,无论如何,您在那里不需要它们。我不会每次都删除,因为它会减慢速度。如果同时发生另一次插入并且我删除了 11 条或更多记录,则不会影响此过程的行为。对于它必须达到的目的而言,它是安全的。
即使表为空,新的 id 也会继续增长,因为您已将 id 声明为自动增量。
更新:我想澄清为什么 ID 生成没有包含在事务中以及为什么不应该包含在事务中。
如果您生成自动 ID 并回滚事务,则下一个自动 ID 无论如何都会递增。摘自 MySQL 错误报告:
使用此过程获取 ID 是完全线程安全的。获取 ID 后的逻辑应该包装在事务中,尤其是在处理多个表时。
以这种方式获取序列并不是一个新概念,例如 metabase_mysql.php 是一个稳定的数据库访问库,有一个名为 GetSequenceNextValue() 的方法,它非常相似。
You can create a table with auto increment id just to keep track of ids. Your program would do an insert on that table, get the id, use it as necessary.
Something along the lines of:
Where seq_table is a table that you've to create just to get the ids. Make it a function so it can be used whenever you need. Every 10 ids generated I delete all generated ids, anyway you don't need them there. I don't delete every time since it would slow down. If another insert happen in the meantime and I delete 11 or more records, it doesn't affect the behaviour of this procedure. It's safe for the purpose it has to reach.
Even if the table is empty new ids will just keep on growing since you've declared id as auto-increment.
UPDATE: I want to clarify why the ID generation is not wrapped in a transaction and why it shouldn't.
If you generate an auto id and you rollback the transaction, the next auto id, will be incremented anyway. Excerpt from a MySQL bug report:
Getting the ID with this procedure is perfectly thread safe. Your logic after the ID is obtained should be wrapped in a transaction, especially if you deal with multiple tables.
Getting a sequence in this way isn't a new concept, for instance, the code of metabase_mysql.php which is a stable DB access library has a method called GetSequenceNextValue() which is quite similar.
在单个表中,您可以有一个
内容类型
字段和包含内容类型
字段的聚集
索引。这有效地将所有一种内容类型保留在光盘上的一个位置,并将另一种内容类型保留在另一个位置,等等。(它实际上组织成页面,但这种物理组织仍然如此。)假设每种内容类型具有相同的字段,这可能会满足您的需求,并且行为与多个表类似。在某些情况下,您甚至可能会发现,通过适当的索引,单表解决方案可以更快、更方便且可维护等。例如尝试跨所有内容类型创建全局唯一标识符。
如果您无法将它们合并回单个表,您可以创建一个中央链接表...
在插入内容表时,也插入链接表以创建您的全球唯一 ID。
更简单,但更手动,只需在数据库中的某个位置保存一个值即可。每当您需要新的 ID 时,请使用该集中存储的值并将其加一。请务必将增量和集合包装在单个事务中以停止竞争条件。 (这可以通过多种方式完成,具体取决于您的 SQL 风格。)
编辑
来自网络的几行 MySQL 示例代码...
就个人而言,我实际上会将值存储在变量中,提交事务,然后继续我的业务逻辑。这将使表上的锁保持在最低限度。
In a single table, you could have a field for the
content type
andclustered
index that includes thecontent type
field. This effectively keeps all of one content type in one place on the disc, and another content type in another place, etc. (It's actually organised into pages, but this physical organisation is still true.)Assuming that each content type has the same fields, this would likely meet your needs and behave similarly to multiple tables. In some cases you may even find that, with appropriate indexes, a single table solution can be faster, more convenient and maintainable, etc. Such as trying to create global unique identifiers across all content types.
If you're unable to merge these back into a single table, you could create a central link table...
As you insert into the content tables, also insert into the link table to create your globally unique id.
More simply, but even more manually, just hold a single value somewhere in the database. Whenever you need a new id, use that centrally stored value and increment it by one. Be sure to wrap the increment and collection in a single transaction to stop race conditions. (This can be done in a number of ways, depending on your flavor of SQL.)
EDIT
A couple of MySQL example lines of code from the web...
Personally, I'd actually store the value in a variable, commit the transaction, and then continue with my business logic. This would keep the locks on the tables to a minimum.
您可以有一个单独的 ID 表,将其插入其中,然后使用新插入的 ID。
例如
在脚本中:
添加错误检查等以适应口味。
MySQL 手册指出:
(来源)所以我不要认为对 ACID 合规性的担忧是一个问题。
You could have a separate ID table, insert into that, and use the newly-inserted ID.
e.g.
In the script:
Add error checking etc. to taste.
The MySQL manual states:
(Source) So I don't think concerns about ACID complians are a problem.