频繁选择和插入的数据库设计

时间:2014-03-10 05:36:43

标签: sql sql-server database database-design

我想知道以下案例的最佳数据库设计。

我使用SpringSql Server,我的案例可以简化如下:

假设这里有三张表:

项目:

  • id(唯一,主键,自动增加)
  • 姓名
  • 类别

地址:

  • id(唯一,主键,自动增加)
  • 地址
  • 邮政编码

订单:

  • ID(唯一的,主键,自动增加)
  • 价格
  • 日期
  • 的itemId(外键)
  • addressId(外键)

业务逻辑Spring处理传入消息,包括项目,地址和订单信息。

如果传入的项目数据存在于数据库中(存在意味着名称和类别相同),则返回该记录的ID。它不存在,插入新记录并返回新的id。

地址几乎相同。如果传入的地址数据存在于数据库中(存在意味着地址和邮政编码相同),则返回该记录的id。它不存在,插入新记录并返回新的id。

然后将前一项ID和地址id作为外键插入到订单表中。

我现在所做的就是将所有这些选择并将逻辑插入到一个存储过程中,以减少服务器与数据库通信之间的延迟。

我想知道这种情况是否有更好的解决方案。


更新

以下是我使用的Proc

CREATE procedere spInsert

--list of parameters

set @tmpItemId = (select id from item where name=@name and category=@category)

if @tmpItemId is NULL

   begin 
       insert to item values(@name,@category)
       set @tmpItemId=@@IDENTITY
   end

--the same logic applied to Address

insert into order values(@price,@date,@tmpItemId,@tmpAddressId)

测试一段时间后,速度不满足,插入100条记录大约需要10-20秒。

我可以问任何改进的方法吗?

顺便说一下,我认为存储过程的瓶颈是关于每次选择id并频繁插入。那么使用uuid作为表的索引而不是自动增加数据库中的索引呢?这样,Java端可以处理选择部分,因为Java端提供uuid,而sql server只关心insert

这是一个不错的选择吗?

5 个答案:

答案 0 :(得分:0)

您计划在一个存储过程中处理所有这3个数据库事务是最佳解决方案,除非您预见到死锁情况,即多个用户同时尝试添加相同的订单(相同的地址和项目)。

答案 1 :(得分:0)

使用存储过程是减少网络流量时间的好方法。你在那里跟踪。

以下是两种可能的数据建模调整:

  1. 如果您提前了解所有商品/类别,则可以预先填充数据。这样它只是一个选择获取ID。然后,您提前完成所有插入工作。

  2. 您可以通过将项目表更改为使用自然键(名称和类别)来更进一步。 然后,您甚至不必触摸此方案中的项目表。缺点是您必须在订单表上存储整个项目名称和类别。所以你会牺牲一些存储空间来加速这个过程。另一个好处是,阅读订单表将使用少一个连接来获取项目名称和类别。

答案 2 :(得分:0)

  1. 就像你说的那样,你没有展示完整的桌面设计。所以看得见的东西看起来都不错。
  2. 所以现在一切都取决于proc内容,并且一次取决于你传递给这个过程的内容和内容。

  3. 希望itemid和addressid在订购表中不为空。例如itemid是新的但是addressid已经存在,所以你如何在订单表或你的proc中插入/处理这种情况。

  4. 就像你可以使用TVP一样,合并,在这个链接中讨论类似的主题,http://forums.asp.net/p/1956468/5582681.aspx?Re+Insert+Millions+of+records

答案 3 :(得分:0)

选择设计时需要考虑几个因素。以下是一对夫妇:

  1. 数据集有多大? 如果数据集很小,那么您的解决方案将起作用。随着行数的增加,文本搜索可能会变慢。一个非常大的数据库可能无法使用id的自动增加值。
  2. 是否有更多必须处理的业务规则?例如,如果找不到完全匹配,程序是否会返回紧密匹配?如何实现业务规则的逻辑和错误处理可以产生影响。如果有很多关于验证好的项目,地址或订单行的规则,最好将代码分成不同的存储过程,以便更容易调试并隔离代码更改的连锁效应。未来似乎总会带来不断变化的商业环境。
  3. 为了使表更具可读性,在Item name中,键itemId和Address表中的键名为addressId。尝试消除假设,因为没有两个人有完全相同的经验,可能从名称中得出不同的初步结论。
  4. 实际的业务规则和插入代码可以进入表的触发器。然后,存储过程将插入到项目中,并在成功时插入到地址中,并在成功时插入到订单中。这将使单个执行计划更简单,这将使优化更容易弄清楚。再次,分离业务规则会减少范围维护和测试。

答案 4 :(得分:0)

您的解决方案足以进行频繁的选择和插入。你不需要改变其他解决方案。