Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在SQL中为多个表实现全局递增id?_Php_Mysql_Sql_Database Design - Fatal编程技术网

Php 如何在SQL中为多个表实现全局递增id?

Php 如何在SQL中为多个表实现全局递增id?,php,mysql,sql,database-design,Php,Mysql,Sql,Database Design,我在编写代码时决定为每种类型的内容使用不同的表。现在我要解决这个问题了。基本上,我的通知系统根据当前的时间戳对最新内容进行排序。这是不准确的,但是,因为有一个小的机会,有人会提交内容的同时,另一个人,不正确的排名将发生 现在,如果我将所有内容放在一个表中,我只需通过一个自动递增的变量对其进行排序。是否有一种方法可以跨多个表实现此自动递增整数(例如,当有东西插入到表1中,id=0,有东西插入到表2中,id=1)。或者我必须把我所有的东西重新编码到一张桌子上 注意: 我之所以将内容放在多个表中,是因

我在编写代码时决定为每种类型的内容使用不同的表。现在我要解决这个问题了。基本上,我的通知系统根据当前的时间戳对最新内容进行排序。这是不准确的,但是,因为有一个小的机会,有人会提交内容的同时,另一个人,不正确的排名将发生

现在,如果我将所有内容放在一个表中,我只需通过一个自动递增的变量对其进行排序。是否有一种方法可以跨多个表实现此自动递增整数(例如,当有东西插入到表1中,id=0,有东西插入到表2中,id=1)。或者我必须把我所有的东西重新编码到一张桌子上

注意:

我之所以将内容放在多个表中,是因为它是有组织的,可以减少负载压力。我不再真正关心组织,因为我可以通过我编写的GUI访问数据,我只是想知道负载压力

编辑:


我将PHP5与MySQL结合使用。

您可以创建一个具有自动增量id的表来跟踪id。您的程序将在该表上进行插入,获取id,并根据需要使用它

大致如下:

function getNextId() {
    $res = mysql_query("INSERT INTO seq_table(id) VALUES (NULL)");
    $id = mysql_insert_id();
    if ($id % 10 == 0) {
        mysql_query("DELETE FROM seq_table");
    }
    return $id;
}
其中,seq_table是一个表,您必须创建它来获取ID。使其成为一个函数,以便在需要时随时使用。每生成10个ID,我就会删除所有生成的ID,反正你不需要它们。我不会每次都删除,因为它会变慢。如果同时发生另一次插入,并且我删除了11条或更多记录,则不会影响此过程的行为。就它必须达到的目的而言,它是安全的

即使表是空的,新的id也会继续增长,因为您已经将id声明为自动增量

更新:我想澄清为什么ID生成没有包装在事务中,为什么不应该包装在事务中

如果生成自动id并回滚事务,则下一个自动id仍将递增。摘自一篇文章:

[…]这不是一个bug,而是我们知道的每个RDBMS中都会出现的预期行为。生成的值不是事务的一部分,它们不关心其他语句

使用此过程获取ID是完全线程安全的。获取ID后的逻辑应该包装在事务中,特别是处理多个表时


以这种方式获取序列并不是一个新概念,例如,它的代码是一个稳定的DB访问库,它有一个名为GetSequenceNextValue()的方法,这个方法非常类似

在单个表中,您可以为
内容类型
聚集
索引设置一个字段,其中包括
内容类型
字段。这有效地将所有一种内容类型保存在光盘上的一个位置,将另一种内容类型保存在另一个位置,等等(它实际上被组织成页面,但这种物理组织仍然是正确的)

假设每个内容类型都有相同的字段,这可能会满足您的需要,并且其行为类似于多个表。在某些情况下,您甚至可能会发现,使用适当的索引,单个表解决方案可以更快、更方便、更易于维护等,例如尝试跨所有内容类型创建全局唯一标识符


如果无法将这些内容合并回单个表中,可以创建一个中心链接表

CREATE TABLE content_link (
  id            INT IDENTITY(1,1),         -- MS SQL SERVER syntax
  content_type  INT,
  content_id    INT                        -- The id from the real table
)
在插入内容表时,也要插入链接表以创建全局唯一id


更简单但更手动的是,只需在数据库中的某个位置保存一个值。每当您需要一个新的id时,使用该集中存储的值并将其递增一。确保在单个事务中包装增量和集合以停止竞争条件。(这可以通过多种方式完成,具体取决于您的SQL风格。)

编辑

来自web的两行MySQL示例代码

START TRANSACTION;
INSERT INTO foo (auto,text)
    VALUES(NULL,'text');         # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table
COMMIT TRANSACTION;


就个人而言,我实际上会将值存储在变量中,提交事务,然后继续我的业务逻辑。这将使表上的锁保持在最小值。

您可以有一个单独的ID表,插入其中,然后使用新插入的ID

e、 g

在脚本中:

<?php
$r = mysql_query('INSERT INTO ids (timeadded) VALUES (NOW())');
$id = mysql_insert_id();
mysql_query("INSERT INTO someOtherTable (id, data) VALUES ('$id', '$data)");

您的问题,特别是需要跨越多个表的ID,清楚地表明您的数据库设计需要更改。您应该为所有内容类型创建一个具有自动递增ID的表(作为泛化)。然后,对于每个特定的内容类型,您可以定义另一个具有额外字段和外键指向基本表的表(相当于OOP中的继承)


换句话说,您需要这样的东西。

无论您使用的是日期时间还是任意排名,如果两个人同时提交一个新项目,那么这两个值不应该相同吗?我的意思是,你还想要什么行为?@Jordan-一个任意顺序,但每次查询时都是固定的,而不是随机确定的?@Dems在这种情况下,OP应该只按第二列排序,这样具有相同列的行将始终以相同的顺序出现。说真的,这很好。我从来不知道这个mysql\u insert\u id()函数。让它更容易,不再记录噩梦!我仍然需要测试它,但它应该可以工作。有一个问题,使用DELETE FROM seq_table,这不会删除所有行吗?如果是这样,那会从mysql_insert_id()中删除数据吗?您的代码中还有一个错误,PHPNote中没有int:这涉及到至少两次到SQL server的访问。(一个更新表,并将id返回到php脚本,第二个将其用于您的业务逻辑。)此开销在低容量时可以忽略不计,但在高容量情况下可能会增加
<?php
$r = mysql_query('INSERT INTO ids (timeadded) VALUES (NOW())');
$id = mysql_insert_id();
mysql_query("INSERT INTO someOtherTable (id, data) VALUES ('$id', '$data)");