Database 甲骨文:处理标志的最佳实践

Database 甲骨文:处理标志的最佳实践,database,oracle,database-design,relational-database,Database,Oracle,Database Design,Relational Database,我为一家DVD店设计了一个ER图,它只允许注册客户租用,任何人都可以购买。DVD在购买后显然不能出租 每一张DVD都可以购买 问题: 在数据库中强制执行DVD购买后不能出租的最佳方法是什么 我的解决方案: 我在DVD中有一个sell_标志,它是一个字符(1字节)。如果出售,则存储1;如果购买或出租,则存储0。因此,如果它是一个,它不能被租用 同样,如果DVD正在出租,它也会有一个标志。如果租用,则存储一个,如果可以租用或购买,则存储零个 这两个标志是否是处理这些问题的最佳方法 我把它们串成字符(

我为一家DVD店设计了一个ER图,它只允许注册客户租用,任何人都可以购买。DVD在购买后显然不能出租

每一张DVD都可以购买

问题:

在数据库中强制执行DVD购买后不能出租的最佳方法是什么

我的解决方案:

我在DVD中有一个sell_标志,它是一个字符(1字节)。如果出售,则存储1;如果购买或出租,则存储0。因此,如果它是一个,它不能被租用

同样,如果DVD正在出租,它也会有一个标志。如果租用,则存储一个,如果可以租用或购买,则存储零个

这两个标志是否是处理这些问题的最佳方法

我把它们串成字符(1字节)这是存储它们的最好方法吗

情况:

会员(会员人数、姓名、地址、电话号码、加入日期)

DVD(DVD\u ID、电影\u ID、售出标志、租用标志)

租赁(会员数量、DVD数量、租赁日期、退货日期、价格、罚款)

购买(DVD\u ID,会员数量,价格,售出日期)

电影(电影ID、导演、姓名、租金、售价)


出售和租赁不需要两个单独的标志,因为这两个州是相互排斥的。如果DVD售出,则不能同时租用;同样,反之亦然。也许一个更好的替代品是一个“状态”栏,上面写着1-Available、2-Rened和3-Seld。可能是不同状态的查找表

不过,您必须以编程方式强制执行此规则,因为该规则适用于“租赁过程”,而不是表示DVD或租赁或客户事实的静态数据

你基本上是这样说的——“在租赁时,如果有人选择了已经售出的DVD,则不允许租赁交易”

因此,在您的程序/功能中

PROCEDURE RENT_DVD (member_num, dvd_id, rented_on, price) 
开头会有一张支票,比如

FUNCTION is_dvd_rentable(dvd_id) return boolean
确认DVD的状态不是3


您可能会尝试将逻辑放在触发器中,该触发器可能会说“如果状态=3,则不允许此租赁交易完成”“。但如果您经常访问此网站或其他与oracle相关的网站,如asktom,您就会知道业务逻辑永远不应该放在触发器中

我建议在您的图表中,将实体购买和租赁替换为单个订单实体

在Orders实体上放置orderType属性“purchase”或“rental”

简单的数据库约束可以强制要求DVD只能出现在单个订单行上

因此:

客户已订购DVD


订单是一种类型。

您为什么需要该标志?你也可以说“如果Retra存在于DVD上,它就不能被购买”——反之亦然。@JensKrogsboell完全正确。对于您的最终用例,如果存在活动租赁(返回的任何匹配租赁为空),则不允许租赁。好主意。尽管我认为多个表可以帮助OP更好地定义实体。在单个订单表中,您可能会有诸如Rendered_on、returned_on、late_fine、Seld_on等列,这些列仅适用于各自类型的订单,而不适用于所有类型的订单。当您包含了未定义数据结构的属性时,您可能违反了一些数据规范化规则。超类型子类型的情况可能会有所帮助。订单作为超类型。在orders表中定义唯一约束,然后转到子类型并获取其他子类型attributes@ruudvan您可以根据OrdeType将处理细节保存在两个单独的表中-例如PurchaseOrderDetails和RentalOrderDetails:“订单包含PurchaseOrderDetails或RentalOrderDetails。”