我想知道以下案例的最佳数据库设计。
我使用Spring
和Sql Server
,我的案例可以简化如下:
假设这里有三张表:
项目:
地址:
订单:
业务逻辑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
这是一个不错的选择吗?
答案 0 :(得分:0)
您计划在一个存储过程中处理所有这3个数据库事务是最佳解决方案,除非您预见到死锁情况,即多个用户同时尝试添加相同的订单(相同的地址和项目)。
答案 1 :(得分:0)
使用存储过程是减少网络流量时间的好方法。你在那里跟踪。
以下是两种可能的数据建模调整:
如果您提前了解所有商品/类别,则可以预先填充数据。这样它只是一个选择获取ID。然后,您提前完成所有插入工作。
您可以通过将项目表更改为使用自然键(名称和类别)来更进一步。 然后,您甚至不必触摸此方案中的项目表。缺点是您必须在订单表上存储整个项目名称和类别。所以你会牺牲一些存储空间来加速这个过程。另一个好处是,阅读订单表将使用少一个连接来获取项目名称和类别。
答案 2 :(得分:0)
所以现在一切都取决于proc内容,并且一次取决于你传递给这个过程的内容和内容。
希望itemid和addressid在订购表中不为空。例如itemid是新的但是addressid已经存在,所以你如何在订单表或你的proc中插入/处理这种情况。
答案 3 :(得分:0)
选择设计时需要考虑几个因素。以下是一对夫妇:
答案 4 :(得分:0)
您的解决方案足以进行频繁的选择和插入。你不需要改变其他解决方案。