首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关键问题:我应该在数据库中使用哪种关键策略?

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

Stack Overflow用户
提问于 2009-12-30 10:35:31
回答 6查看 229关注 0票数 1

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

我想存一份10件的订单。所订购的物品属于订单。因此,我存储订单,向数据库询问最后插入的id (这在并发性方面很危险,对吗?),然后用外键(order_id)存储这10项。

所以我总是要做:

插入..。

last_inserted_id = db.lastInsertId();

插入..。插入..。插入..。

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

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

A)不要使用auto_increment密钥!使用键表?键表将有两个字段:table_name, next_key。每次我需要一个键来插入一个新的数据集时,我首先通过访问一个特殊的静态next_key类方法来请求这个KeyGenerator。这做了一个选择和更新,如果可能的话,在一个事务(这会起作用吗?)。当然,我会要求每个受影响的桌子。接下来,我可以在一个事务中插入我的整个对象图,而无需与数据库玩乒乓游戏,在我事先知道键之前。

B)对密钥使用GUUID / UUID算法吗?--假设它们在世界范围内是非常独特的,而且它们很大。我是说. L_A_R_G_E因此,大量的记忆会进入这些巨大的钥匙。索引会很难,对吧?数据检索对数据库来说将是一个痛苦--至少我想--整数键处理起来要快得多。另一方面,这些也提供了一些安全性:访问者不能再通过增量id参数来迭代所有订单或所有用户或所有图片。

C)坚持使用auto_incremented键吗? Ok,如果是这样的话,那么上面示例中描述的事务呢?我该怎么解决呢?也许首先插入一个Ghost行,然后用一个UPDATE +n插入一个事务?

D)还有什么?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-12-30 10:43:18

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

根据数据库和连接器的不同,最后一个insert-id函数返回的值可能与事务无关。例如,使用MySQL,mysql_insert_id从该特定客户端返回最后一个查询的标识符(不受其他客户端并发执行的操作的影响)。

票数 3
EN

Stack Overflow用户

发布于 2009-12-30 10:43:17

你用的是哪个数据库?

是的,通常插入一个记录,然后尝试再次选择它以查找自动生成的键是错误的,特别是当您使用表查询中的朴素select max(id)时。这是因为当两个线程正在创建记录时,max( id )可能实际上不会返回当前线程使用的最后一个id。

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

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

票数 2
EN

Stack Overflow用户

发布于 2009-12-30 10:41:45

Server支持标识(Transact-SQL),它应该处理事务问题和并发问题。

我会说坚持auto_increment.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1979495

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档