我在工作区a和工作区B有一个数据库。
联机时,此数据库的副本始终从两个工作区更新。
另外,当其他工作区进行任何更改时,这两个工作区都可能需要更新其数据库。
一切正常,但我的问题是:例如,有两个表StockOrders,在Orders中有一列是stock_id
如果工作区A使用自动递增的“Stock_id”=23创建一个新的“Stock X”,而工作区B使用自动递增的“Stock_id”=23创建一个新的“Stock Y”,则工作区B将添加工作区A的“Stock X”,工作区B将添加工作区B的“Stock Y”,但每个数据库中的id都不同。
当工作区A对stock_id=23下了一个“stock X”的订单时,当这个查询发送到中央数据库,然后发送到工作区B时,它将插入订单,但是stock_id=23将引用“stock Y”。
我非常感谢您的帮助,谢谢:)

最佳答案

编辑:
您的原始设计使用AUTO INCREMENT列作为主键。问题是,正如您看到的,当数据同时进入最终合并的单独数据库时,您最终会创建重复的键。
另一种方法是在每个不同的数据库中使用一个序列。不幸的是,序列在mysql中本机不可用(许多其他数据库,如Oracle、db2都有序列——它们允许这种类型的分布式数据库插入,不存在冲突)。AUTO INCREMENT列不允许所需的复制类型。
所以,你只有两个选择。
1)添加设置位置id的主键的额外部分(根据第一个答案)。
2)或者使用自己的序列手工生成插入的id,而不是使用AUTO INCREMENT列。
最好将一个序列实现为一个存储的proc/函数,当它获得序列中的下一个值时提交它自己——这可能会导致值不被使用。这很好——如果您等待提交序列号,直到提交整个插入,这比争用要好。
最主要的是,当您执行第一次插入时,您使用存储过程中的序列。当您有效地将数据复制到第二个数据库时,您将使用原始数据库所在行中生成的序列。在每个单独的db w/不同的起点上保持顺序以防止碰撞。
例如,在每个数据库中,您需要两个部分:
1)保存每个命名序列的下一个可用序列号的表。(从序列中获取主键的每个表都会获取一个条目)。
2)访问和更新下一个序列号的表的函数。
一个示例实现是:
序列表:

CREATE TABLE sequences (
  name varchar(30) NOT NULL,
  value int(10) unsigned,
  PRIMARY KEY (name)
) ENGINE=InnoDB

序列函数:
delimiter //
create function get_next_value(p_name varchar(30)) returns int
  deterministic
  sql security invoker
begin
  declare current_val integer;
    UPDATE sequences
    SET value = (@current_val:=value) + 1
    WHERE name = p_name;

  return @current_val;
end //
delimiter ;

主要的问题是,存储的函数需要是一个单独的语句,以便它完成并立即提交(否则,您将拥有一个锁,当订单进入时,它将导致您的事务堆叠在彼此后面。如果您没有很高的吞吐量,这就不是什么大问题。
我没有写这个函数——我只是从这里大量地复制它:http://www.bigdbahead.com/?p=185我将向您介绍更多细节。(如果那个用户在这里找到我,我很乐意让他写一个答案,并在这里给他适当的评价)。
现在,对于每个数据库,使用不同的数字初始化该值以避免冲突。因此,对于orders表,在位置A中,您可以使用以下命令初始化它:
insert into sequences ('orders', 1);

在位置B,你可以用以下方法初始化它:
insert into sequences ('orders', 1000000);

然后在两个数据库中,在插入orders时,您将执行以下操作:
insert into orders (order_id, . . .)
select mysql.get_next_value('user_id'), . . . <hardcoded-values>

--
我还并没有对这个解决方案进行路试——把它作为我在回答中关于序列的建议的大纲。您应该跟踪上面的blog entry链接,该链接提供了一些更详细的信息,特别是关于如何在事务控制下工作的信息,查看注释(我从注释中获取了函数的一种形式,而不是原始函数),当然,还要在负载下测试它。

关于php - 使用外键合并两个数据库时的SQL问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10154953/

10-11 04:47
查看更多