我有優惠券表。優惠券只適用於某些物品或適用於整個類別的物品。如何在數據庫中創建和/或關係?
例如:$ 5優惠券比薩餅12" 和(1L百事可樂OR薯條)
最好我能想出是使含有coupon_id和有點CouponMenuItems表如IsOr和IsAnd。它不起作用,因爲我在這個例子中有2組項目,第二個項目是2項目之間的OR關係
任何想法,我怎麼能做到這一點邏輯實施儘可能簡單嗎?
任何幫助或提示表示讚賞!
感謝,
Teebot
我有優惠券表。優惠券只適用於某些物品或適用於整個類別的物品。如何在數據庫中創建和/或關係?
例如:$ 5優惠券比薩餅12" 和(1L百事可樂OR薯條)
最好我能想出是使含有coupon_id和有點CouponMenuItems表如IsOr和IsAnd。它不起作用,因爲我在這個例子中有2組項目,第二個項目是2項目之間的OR關係
任何想法,我怎麼能做到這一點邏輯實施儘可能簡單嗎?
任何幫助或提示表示讚賞!
感謝,
Teebot
通常,您可以通過使用Disjunctive Normal Form來簡化這種事情。
你將你的邏輯標準化爲一系列的不連貫 - 「或子句」。每個分離符都被設置爲「和子句」。
所以你的規則成爲下面的長分隔符。
OR
(你總是可以做到這一點,順便說一句,與任何邏輯問題米是有些事情可能會非常複雜。好消息是沒有營銷人員會試圖對你產生困惑的邏輯。此外,從任何舊形式到分離正態形式的重寫都是一種簡單的代數。)
這個,你會注意到,總是兩層深:總是一個頂層的不連續的列表(任何其中一個可能是真實的)和一個較低級別的連詞列表(所有這些都必須是真實的)。
因此,您有一個「條件」表,其中包含id和產品名稱等列。這定義了訂單項和產品之間的簡單比較。
你有一個Conjuncts(「中級和子句」)表,其中包含像連接ID和條件ID這樣的列。連詞與條件之間的連接將產生連詞的所有條件。如果所有這些條件都是真的,那麼合併是真實的。
擁有一個Disjuncts(「頂級或子句」)表,其中包含像disjunct Id和conjunct ID這樣的列。如果其中一個斷言是真實的,則斷言是真實的。
分離符,連詞和條件之間的連接會產生一組需要測試的條件。
不錯的。我自己也是爲了類似的問題做了這個。它似乎比起一個更「關係」的方法來說更復雜,但實際上它很自然地適用於「優惠券」(在我的情況下爲特價)場景。 – Draemon 2008-10-24 01:50:15
你可以把單個項目作爲自己的組(1件),只是實現純邏輯券映射到組。
您需要將所有關係組合在一起,定義它們如何分組,然後將優惠券分配給這些關係。從本質上講,你需要數據庫實體來表示你的榜樣括號,但你需要一個或多個外層的括號:
(比薩12" AND(1L百事可樂或薯條))
Coupon
CouponId
Name
...
Item
ItemId
Name
...
Group
GroupId
GroupMembership
GroupMembershipId
GroupId
ItemId
ItemAssociation
ItemAssociationId
Item1Id
Item2Id
IsOr : bit -- (default 0 means and)
GroupAssociation
GroupAssociationId
Group1Id
Group2Id
IsOr : bit -- (default 0 means and)
集思廣益這個結構之後它看起來像是一個可以用節點父/子關係層次結構解決的問題。ItemAssociation/GroupAssociation表氣味對我來說,我認爲一個可以處理的通用關聯表可能是可取的,因此您可以編寫通用代碼來處理所有關係(儘管你會失去參照完整性,除非你也將項目和組概括爲一個實體)。
注意:同時命名實體組可能會產生問題。 :)
一種可能的方法來考慮。假設您創建了以下類別:
+----------+ 1 +---------------+ *
| Coupon |<#>------>| <<interface>> |<--------------+
+----------+ | CouponItem | |
| +value | +---------------+ |
+----------+ | +cost() | |
+---------------+ |
/|\ |
| |
+--------------------------------+ |
| | | |
LeafCouponItem AndCouponItem OrCouponItem |
<#> <#> |
| | |
+-------------+---------+
和:
class Coupon {
Money value;
CouponItem item;
}
interface CouponItem {
Money cost();
}
class AndCouponItem implements CouponItem {
List<CouponItem> items;
Money cost() {
Money cost = new Money(0);
for (CouponItem item : items) {
cost = cost.add(item.cost());
}
return cost;
}
}
class OrCouponItem implements CouponItem {
List<CouponItem> items;
Money cost() {
Money max = new Money(0);
for (CouponItem item : items) {
max = Money.max(max, item.cost);
}
return max;
}
}
class LeafCouponItem implements CouponItem {
Money cost;
Money cost() {
return cost;
}
}
並映射到2個表:
COUPON COUPON_ITEM
------ -----------
ID ID
VALUE COUPON_ID (FK to COUPON.ID)
DISCRIMINATOR (AND, OR, or LEAF)
COUPON_ITEM_ID (FK to COUPON_ITEM.ID)
DESCRIPTION
COST
因此,對於你的例子中,你將有:
> SELECT * FROM COUPON
ID 100
VALUE 5
And
> SELECT * FROM COUPON_ITEM
ID COUPON_ID DISCRIMINATOR COUPON_ITEM_ID DESCRIPTION COST
200 100 AND NULL NULL NULL
201 100 LEAF 200 PIZZA 10
202 100 OR 200 NULL NULL
203 100 LEAF 202 PEPSI 2
204 100 LEAF 202 FRIES 3
這種單表方法高度非規範化,有些人寧願爲每個CouponItem實現分開表。
大多數ORM框架將能夠照顧這樣一個類的域的存在。
我的建議:
Table
primary key
= = = = =
COUPONS
coupon_id
PRODUCT_GROUPS
group_id
ITEM_LIST
item_id
ITEM_GROUP_ASSOC
item_id, group_id
COUPON_GROUP_ASSOC
coupon_id, group_id
COUPON_ITEM_ASSOC
coupon_id, item_id
在COUPON_ITEM_ASSOC
表中,有一個字段指示優惠券可以有多少項申請一次,與一些特殊的值,表示「無限」。
相信與否這不是一項家庭作業:)這是一個在線列表的當地餐館,您可以從網上訂購。老闆讓我把這個邏輯添加到他的網站上。 – teebot 2008-10-23 12:15:00