Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.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
Mysql 如何解决这个外键问题?_Mysql_Database_Database Design - Fatal编程技术网

Mysql 如何解决这个外键问题?

Mysql 如何解决这个外键问题?,mysql,database,database-design,Mysql,Database,Database Design,我正在开发一个会计应用程序,其中每个交易都有一个密钥。 例如:在销售交易中有两个条目,一个用于销售账户,另一个用于客户。 id | trid |日期|账户|金额 112 | 33 | 01-04-2013 |销售A\c | 300.00 113 | 33 | 01-04-2013 |客户A\c | 300.00 114 | 34 | 01-04-2013 |销售A\c | 110.00 115 | 34 | 01-04-2013 |客户1 A\c | 110.00 116 | 35 | 0

我正在开发一个会计应用程序,其中每个交易都有一个密钥。 例如:在销售交易中有两个条目,一个用于销售账户,另一个用于客户。

id | trid |日期|账户|金额


112 | 33 | 01-04-2013 |销售A\c | 300.00
113 | 33 | 01-04-2013 |客户A\c | 300.00
114 | 34 | 01-04-2013 |销售A\c | 110.00
115 | 34 | 01-04-2013 |客户1 A\c | 110.00
116 | 35 | 01-04-2013 |销售A\c | 250.00
117 | 35 | 01-04-2013 |客户2 A\c | 250.00

这里,TRID是MAX(TRID)+1。这个概念在单用户环境中很好地工作,但在多用户环境中,应用程序由多个用户同时使用,一个或多个用户可以获得相同的TRID


解决方案是什么?

在创建原子操作的过程中,您需要使用事务并锁定表-这将确保没有两个进程使用相同的值

您需要将过程组合起来,但基本上是:

-- start transaction
-- lock table
-- select max(trid) + 1 and store in a variable
-- do your inserts
-- unlock table
-- end transaction

在创建原子操作的过程中,需要使用事务并锁定表-这将确保没有两个进程使用相同的值

您需要将过程组合起来,但基本上是:

-- start transaction
-- lock table
-- select max(trid) + 1 and store in a variable
-- do your inserts
-- unlock table
-- end transaction

首先,如果
TRID
单独需要是唯一的,则将其设置为键(单独设置,而不是与其他字段组合)。这样,无论您在客户机代码中犯了什么错误,DBMS都不会让任何副本进入数据库

在多用户环境中,您可以使用安全地生成唯一值,前提是您不关心生成的值是连续的

OTOH,如果你买不起“洞”,那么:

  • 选择MAX(TRID)+1之前锁定整个表
  • 或者在不锁定的情况下执行相同的
    选择
    ,但如果存在密钥冲突,请准备重试

如果你能帮助的话,我建议不要锁定,因为它会对可伸缩性产生严重的负面影响。

首先,如果
TRID
需要唯一,那么将其作为一个键(单独,而不是与其他字段组合)。这样,无论您在客户机代码中犯了什么错误,DBMS都不会让任何副本进入数据库

在多用户环境中,您可以使用安全地生成唯一值,前提是您不关心生成的值是连续的

OTOH,如果你买不起“洞”,那么:

  • 选择MAX(TRID)+1之前锁定整个表
  • 或者在不锁定的情况下执行相同的
    选择
    ,但如果存在密钥冲突,请准备重试

如果你能帮忙的话,我建议不要锁,因为它会对可伸缩性产生严重的负面影响。

如果表当前处于锁定状态,而另一个用户正在尝试插入记录,会发生什么情况?他们应该只需等待您的事务完成,然后才能允许他们访问表-只要您的事务保持快速,我不希望出现任何问题。但一定要测试一下,可能会在事务中抛出一个
SLEEP
,迫使它花费很长时间,然后在它睡眠时,尝试点击几次,确保他们优雅地等待事务完成,而不是出错。数据锁定时是否可用于只读目的?不确定-锁定是一个复杂的问题,不是我的强项-从文档中尝试,看看这里的内容是否适合您。但是,即使它阻止了阅读,时间也会很短,可能根本不重要——如果你将一个过程延迟15毫秒,他们甚至不会知道。@JoeEnos:你能提供一些代码吗?我试过了,但还是不起作用。事务未锁定表。如果表当前处于锁定状态,而另一个用户正在尝试插入记录,会发生什么情况?他们只需等待您的事务完成,然后才能允许他们访问表-只要您的事务保持快速,我预计不会出现任何问题。但一定要测试一下,可能会在事务中抛出一个
SLEEP
,迫使它花费很长时间,然后在它睡眠时,尝试点击几次,确保他们优雅地等待事务完成,而不是出错。数据锁定时是否可用于只读目的?不确定-锁定是一个复杂的问题,不是我的强项-从文档中尝试,看看这里的内容是否适合您。但是,即使它阻止了阅读,时间也会很短,可能根本不重要——如果你将一个过程延迟15毫秒,他们甚至不会知道。@JoeEnos:你能提供一些代码吗?我试过了,但还是不起作用。事务没有锁定表。您不能只使用GUID进行TRID吗?您不能只使用GUID进行TRID吗?您可以提供一些代码吗?我试过了,但还是不起作用。事务未锁定表。@NitinKabra链接的帖子不包含任何锁定代码。您需要执行以下操作:。注意:您需要锁定整个表,所以只需
选择。。。仅更新代码是不够的。您能提供一些代码吗?我试过了,但还是不起作用。事务未锁定表。@NitinKabra链接的帖子不包含任何锁定代码。您需要执行以下操作:。注意:您需要锁定整个表,所以只需
选择。。。仅用于更新是不够的。