line_item (id, description, parent_id, product_id);
product (id, model);
行项目的示例层次结构
Product A //"parent" "line item"
Option 1 //child "line item"s of "parent"
Option 2
当前数据库数据
line_item:
id | description | parent_id | product_id
-----------------------------------------
1 | Product A | NULL | 20 //has no parent "line item"
2 | Option 1 | 1 | -1 //no product associated with option
3 | Option 2 | 1 | -1 //has "line item" parent with id == 1
product
id | model
--------------
20 | Product A
问题
我不确定如何摆脱" NULL"来自parent_id
。请注意,我在我的-1
中使用了product_id
,我也以类似的方式使用#!/usr/bin/ruby
require 'softlayer_api'
client = SoftLayer::Client.new(username: 'USER', api_key: 'APIKEY')
productOrder = {
'virtualGuests' => [{
'hostname' => 'test',
'domain' => 'mycompany.com',
'primaryBackendNetworkComponent' => { 'networkVlan' => { 'id' => XXXXX } }
}],
'location' => XXXXX,
'packageId' => 46,
'imageTemplateId' => XXXXX,
'useHourlyPricing' => true,
'prices' => [
{'id' => 26125 }, # 1 x 2.0 GHz Core
{'id' => 32597 }, # 1 GB RAM
{'id' => 23065 }, # 100 GB (SAN)
{'id' => 23065 }, # 100 GB (SAN)
{'id' => 34183 }, # 0 GB Bandwidth
{'id' => 24713 }, # 1 Gbps Public & Private Network Uplinks
{'id' => 34807 }, # 1 IP Address
{'id' => 33483 }, # Unlimited SSL VPN Users & 1 PPTP VPN User per account
{'id' => 34241 }, # Host Ping and TCP Service Monitoring
{'id' => 32500 }, # Email and Ticket
{'id' => 35310 }, # NESSUS_VULNERABILITY_ASSESSMENT_REPORTING
{'id' => 23070 }, # REBOOT_REMOTE_CONSOLE
{'id' => 32627 } # AUTOMATED_NOTIFICATION
]
}
order = client['Product_Order'].verifyOrder(productOrder) here
,说"没有"产品"或者"父母"与该特定订单项记录相关联。
首先我需要摆脱它吗?
答案 0 :(得分:1)
NULL是表示无值的正确方法。
此外,对于良好实践,如果在引用父line_item或product_id引用产品的字段parent_id上添加外键,则无法使用-1。
答案 1 :(得分:1)
我认为您希望保持NULL完整,因为它可以用作指示哪些记录是顶级项目。此外,表格似乎已经标准化,因此标准化与您的问题无关。
答案 2 :(得分:1)
首先,你应该用null替换-1。这是完全合法的价值。
在考虑规范化时,空值实际上不起作用,因为如果你有非空值,你只能说功能依赖,所以你不必担心规范化,你的表很好。
你的表是“disjunct is-a”关系的实现,这意味着line_item是“选项”-line(值为parent_id
)或“product”-line (值为product_id
,例如quantity
,...),并且具有公共值id
和description
。 Disjunct意味着它不能同时存在,所以另一个类型的列被设置为null(这就是为什么你“必须”将null替换为null)。
“disjunct is-a”的通常实现是添加type
- 列,它定义了这些可能性中的哪一种(原因更多是实用类型,例如用于约束检查) 。你在这里不需要它,因为没有这个领域你会清楚它是什么样的线,但是我添加它以强调你实际实现的是什么,并且你以标准方式做了所有事情:
line_item:
id | description | line_type | parent_id | product_id
-----------------------------------------------------
1 | Product A | Product | NULL | 20
2 | Option 1 | Option | 1 | NULL
3 | Option 2 | Option | 1 | NULL
最后评论:还有其他可能的“is-a”实现,其中一些是摆脱null(同时引入其他问题),但对于disjunct选项,这是常见的。但既然它会回答你原来的问题(“如果我不想使用null ......”),我也会添加这个问题:
line_item:
id | description
-----------------
1 | Product A
2 | Option 1
3 | Option 2
line_item_product:
line_item_id | product_id
---------------------------
1 | 20
line_item_option:
line_item_id | parent_id
---------------------------
2 | 1
3 | 1
您有一个用于公共列的表(适用于option
和product
两种类型)和一个单独的表,用于表示具有特定列的两种可能性。
这将摆脱你的空。
最大的实际问题是,您必须对两个表line_item_option
和line_item_product
中的“主键”进行更复杂的检查:不允许添加第1行在line_item_option
中它已经在line_item_product
中,但是mysql没有那么容易检查。这就是为什么只有当你有一个“非分离是一个”关系时才使用这种分裂(例如,如果这些行可以同时是产品和选项)。