Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.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 关键问题:我应该在数据库中使用哪种关键策略?_Php_Mysql_Database_Database Design_Primary Key - Fatal编程技术网

Php 关键问题:我应该在数据库中使用哪种关键策略?

Php 关键问题:我应该在数据库中使用哪种关键策略?,php,mysql,database,database-design,primary-key,Php,Mysql,Database,Database Design,Primary Key,问题:当我在数据库中使用自动递增主键时,总是会发生这种情况: 我想储存一份有10件物品的订单。已订购的项目属于该订单。因此,我存储订单,向数据库请求最后插入的id,这在并发性方面是危险的,对吗?然后用外键order_id存储10个项目 所以我总是要做: 插入 最后插入的\u id=db.lastInsertId 插入。。。 插入 插入 我相信这会阻止我在几乎所有需要外键的情况下使用事务 所以。。。以下是一些解决方案,我不知道它们是否真的很好: A不要使用自动增量键!使用密钥表? 键表将有两个字段

问题:当我在数据库中使用自动递增主键时,总是会发生这种情况:

我想储存一份有10件物品的订单。已订购的项目属于该订单。因此,我存储订单,向数据库请求最后插入的id,这在并发性方面是危险的,对吗?然后用外键order_id存储10个项目

所以我总是要做:

插入

最后插入的\u id=db.lastInsertId

插入。。。 插入 插入

我相信这会阻止我在几乎所有需要外键的情况下使用事务

所以。。。以下是一些解决方案,我不知道它们是否真的很好:

A不要使用自动增量键!使用密钥表? 键表将有两个字段:表名、下一个键。每次我需要表的键来插入新数据集时,首先我通过访问一个特殊的静态KeyGenerator类方法来请求下一个\u键。这会进行选择和更新,如果可能,在一个事务中进行选择和更新是否有效?。当然,对于每个受影响的表,我都会要求这样做。接下来,我可以在一个事务中插入我的整个对象图,而不用与数据库打乒乓球,在我事先知道键之前

B对密钥使用GUID/UUID算法? 它们被认为是世界上独一无二的,而且它们很大。我是说。。。L_A_R_G_E.所以这些巨大的钥匙会有大量的内存。索引将很难,对吗?数据检索将是数据库的一大难题——至少我想——整数键处理起来要快得多。另一方面,它们也提供了一些安全性:访问者不能再通过增加id参数来迭代所有订单、所有用户或所有图片

C是否坚持使用自动递增键? 好的,如果是这样的话,那么上面的例子中描述的事务呢?我怎样才能解决这个问题?也许先插入一个重影行,然后用一个UPDATE+n insert执行一个事务

D还有什么?

Sql Server支持哪些应该解决事务问题和并发问题

我要说的是,坚持使用自动增量。

Sql Server支持,它应该能够解决事务和并发问题


我想说,坚持使用自动增量。

假设您使用的是MySQL

向数据库询问最后插入的id,这在并发性方面很危险,对吗

如果使用MySQLs last_insert_id函数,则只能看到会话中发生的情况。所以这是安全的。你提到:

db.last_insert_id()
我不知道它是什么框架或语言,但我会假设它在封面下使用了MySQL的最后一个_insert_id,如果不是的话,这是一个非常无用的数据库抽象

我相信这会阻止我在几乎所有的INSERT案例中使用事务


我不明白为什么。请解释。

假设您使用的是MySQL

向数据库询问最后插入的id,这在并发性方面很危险,对吗

如果使用MySQLs last_insert_id函数,则只能看到会话中发生的情况。所以这是安全的。你提到:

db.last_insert_id()
我不知道它是什么框架或语言,但我会假设它在封面下使用了MySQL的最后一个_insert_id,如果不是的话,这是一个非常无用的数据库抽象

我相信这会阻止我在几乎所有的INSERT案例中使用事务


我不明白为什么。请解释。

您正在使用哪个数据库

是的,通常插入一条记录,然后再次尝试选择它以查找自动生成的键是错误的,特别是如果您使用的是简单的select maxid from table查询。这是因为一旦两个线程创建了记录,maxid实际上可能不会返回当前线程使用的最后一个id

避免这种情况的一种方法是在数据库中创建一个序列。从代码中选择sequence.NextValue,然后使用该值执行插入,或者您可以创建一个更复杂的SQL语句,一次完成此选择和插入。序列是原子/线程安全的


在MySQL中,您可以从执行结果中请求最后一个插入的id,我相信这将始终为您提供正确答案。

您使用的是哪个数据库

是的,通常插入一条记录,然后再次尝试选择它以查找自动生成的键是错误的,特别是如果您使用的是简单的select maxid from table查询。这是因为一旦两个线程创建了记录,maxid实际上可能不会返回当前线程使用的最后一个id

避免这种情况的一种方法是在数据库中创建一个序列。从代码中选择sequence.NextValue,然后使用该值执行插入,或者您可以创建一个更复杂的SQL语句,一次完成此选择和插入。序列是原子/线程安全的

在MySQL中,您可以从t请求最后插入的id 我相信执行结果将始终为您提供正确答案。

在存储订单时,您需要进行事务处理,以防止只有一半的产品添加到数据库中

根据数据库和连接器的不同,最后一个insert id函数返回的值可能与事务无关。例如,使用MySQL,MySQL\u insert\u id返回来自该特定客户端的上一次查询的标识符,而不受其他客户端同时执行的操作的影响。

在存储订单时,您需要事务来防止只有一半的产品添加到数据库中的情况

根据数据库和连接器的不同,最后一个insert id函数返回的值可能与事务无关。例如,对于MySQL,MySQL\u insert\u id返回来自该特定客户端的最后一个查询的标识符,而不受其他客户端同时执行的操作的影响。

D Sequence :在您的DBMS中可能不可用,但如果可用,将优雅地解决您的问题

对于Postgresql,请查看

D序列 :在您的DBMS中可能不可用,但如果可用,将优雅地解决您的问题


对于Postgresql,请看一看这个问题没有最终的一般答案

添加新记录时,可以很容易地使用自动递增列。要在同一事务中将它们用作外键,它们并不那么直接。您需要特定于数据库的命令来获取新创建的密钥。这种技术在某些数据库中很常见,例如sql server

序列似乎更难使用,因为在插入行之前需要获得一个键,但在最后,将它们用作外键更容易。这种技术在某些数据库中很常见,例如oracle

当您使用Hibernate或NHibernate时,不鼓励使用自动递增键,因为某些优化不再可能。建议使用使用使用附加表的hi-lo算法


GUI很强大,例如在不同数据库、系统、断开连接的场景、导入/导出等之间共享数据时。在许多数据库中,大多数表只包含几百条记录,因此内存和性能不是问题。当使用NHibernate时,您会得到一个生成顺序guid的guid生成器,因为某些数据库在键是顺序的情况下性能更好。

这个问题没有最终的一般答案

添加新记录时,可以很容易地使用自动递增列。要在同一事务中将它们用作外键,它们并不那么直接。您需要特定于数据库的命令来获取新创建的密钥。这种技术在某些数据库中很常见,例如sql server

序列似乎更难使用,因为在插入行之前需要获得一个键,但在最后,将它们用作外键更容易。这种技术在某些数据库中很常见,例如oracle

当您使用Hibernate或NHibernate时,不鼓励使用自动递增键,因为某些优化不再可能。建议使用使用使用附加表的hi-lo算法


GUI很强大,例如在不同数据库、系统、断开连接的场景、导入/导出等之间共享数据时。在许多数据库中,大多数表只包含几百条记录,因此内存和性能不是问题。使用NHibernate时,您会得到一个生成顺序guid的guid生成器,因为某些数据库在键为顺序键时性能更好。

您使用的是什么数据库?什么编程语言?不同的数据库/语言具有不同的功能,这些功能可能会有所帮助。PHP/MySQL是最新版本。但我不想把自己限制在这些问题上,我知道甲骨文公司确实有办法解决这个问题;但几乎没有一家价格合理的酒店提供甲骨文服务。所以当涉及到一人秀的网站/平台时。大公司不在乎,他们有自己的服务器mysql的自动增量不是并发性的问题。lastInsertId特定于会话,因此它不受插入到同一表中的其他连接的影响。请确保在任何需要它的SELECT上包含更新。您使用的是什么数据库?什么编程语言?不同的数据库/语言具有不同的功能,这些功能可能会有所帮助。PHP/MySQL是最新版本。但我不想把自己限制在这些问题上,我知道甲骨文公司确实有办法解决这个问题;但几乎没有一家价格合理的酒店提供甲骨文服务。所以当涉及到一人秀的网站/平台时。大公司不在乎,他们有自己的服务器mysql的自动增量不是并发性的问题。lastInsertId特定于会话,因此它不受插入到同一表中的其他连接的影响。请确保在上包含更新

任何需要的选择。好的,所以当我坚持使用mysql_insert_id时,我仍然可以使用事务在一大步中插入订单+100个项目,其中项目获得订单的FK作为他们在InnoDB引擎下的订单的FK吗?@openfrog:是的,记住在插入新订单后第一件事就是调用mysql_insert_id。好的,所以,当我坚持使用mysql_insert_id时,我是否仍然可以使用事务在一大步中插入订单+100个项目,其中项目将获得订单的FK作为其在订单中的FK,假设使用InnoDB引擎?@openfrog:是的,请记住在插入新订单后第一件事就是调用mysql_insert_id。我猜只有Oracle支持这些序列?我使用MySQL——MyISAM或InnoDB。可能会因为事务而使用InnoDB。很多DBs都支持序列,但考虑到您使用的是MySQL,我只会使用Roland描述的最后一个插入id。我想只有Oracle支持这些序列?我使用MySQL——MyISAM或InnoDB。可能会因为事务而使用InnoDB。很多DBs支持序列,但考虑到您使用的是MySQL,我只会使用Roland描述的最后一个插入id。如果表太大,GUID/UUID就太糟糕了。这是因为它们的随机性会导致大量的I/O,除非它不能缓存在RAM中。有一种方法可以从NHibernate获取顺序GUID来解决这个问题。对不起,我错过了。你能详细介绍一下NHibernate的技术吗?它是重新排列的类型1 UUID吗?如果是这样的话,我想补充一些细节。有一些关于它的博客。例如,这个:。它列出了一些不明显的生成guid的示例。如果你看一下这个实现,你会发现它用一个时间戳覆盖了普通GUID的一部分。8.0中有了新东西,如果表太大,那么GUID/UUID就太糟糕了。这是因为它们的随机性会导致大量的I/O,除非它不能缓存在RAM中。有一种方法可以从NHibernate获取顺序GUID来解决这个问题。对不起,我错过了。你能详细介绍一下NHibernate的技术吗?它是重新排列的类型1 UUID吗?如果是这样的话,我想补充一些细节。有一些关于它的博客。例如,这个:。它列出了一些不明显的生成guid的示例。如果您查看实现,您会发现它用时间戳覆盖了普通GUID的一部分