CodeGym /課程 /SQL SELF /用 Foreign Keys 連接 Marketplace 的 schema

用 Foreign Keys 連接 Marketplace 的 schema

SQL SELF
等級 61, 課堂 1
開放

你已經有一個資料庫,也有一些資料表。甚至你已經把資料表填好資料了。現在是時候來顧一下這些資料的完整性啦。

在每個 schema 裡面創建資料表時,系統會自動幫你加上指向同一個 schema 其他表的 foreign keys。現在你要做的是把不同 schema 的表連起來——加上跨 schema 的 foreign keys。

舉例來說,order 這個 schema 裡的 order 表會指向 user schema 裡的 account 表。你要幫這個表加一個 foreign key。SQL 大概會長這樣:

ALTER TABLE "order".order
  ADD CONSTRAINT fk_order_user
  FOREIGN KEY (user_id)
  REFERENCES "user".account(id)
  ON DELETE RESTRICT;

Foreign Keys 清單

總共你要加 40 個 foreign keys :)

product schema:

[product].review.user_id → [user].account.id

商品評論要連到發表評論的使用者。

[product].question.user_id → [user].account.id

商品問題是註冊用戶才能問的。

[product].answer.user_id → [user].account.id

回答也是屬於某個用戶。

order schema:

[order].order.user_id → [user].account.id

下單的人一定是註冊用戶。

[order].order_item.product_id → [product].product.id

訂單項目一定要指向一個商品。

[order].order_item.variant_id → [product].variant.id

如果有選商品的 variant,就必須存在。但 variant 被刪除時,這欄會變成 NULL。

[order].cart.user_id → [user].account.id

購物車屬於某個特定用戶。

[order].cart_item.product_id → [product].product.id

購物車裡的商品必須是有效的商品。

[order].cart_item.variant_id → [product].variant.id

如果有選 variant 就要存在,被刪除時欄位會變 NULL。

logistics schema:

[logistics].inventory.variant_id → [product].variant.id

variant 可能會被刪掉(例如停售)。

[logistics].inventory_movement.product_id → [product].product.id

倉庫的任何移動都要對應到實際商品。

[logistics].inventory_movement.variant_id → [product].variant.id

移動可以是針對某個商品 variant。

[logistics].stock_level.product_id → [product].product.id

庫存水準是根據現有商品設定的。

[logistics].transfer.product_id → [product].product.id

移動只針對真的存在的商品。

[logistics].transfer.variant_id → [product].variant.id

variant 可能會被刪掉。

[logistics].package.order_id → [order].order.id

每個包裹都要連到一個訂單。

payment schema:

[payment].payment_transaction.order_id → [order].order.id

付款交易一定要對應到訂單。

[payment].invoice.order_id → [order].order.id 發票是根據訂單開的。

[payment].billing_address.user_id → [user].account.id

帳單地址屬於某個用戶。

[payment].wallet.user_id → [user].account.id

錢包對每個用戶都是唯一的。

marketing schema:

[marketing].discount.product_id → [product].product.id

折扣可以綁定到某個商品。

[marketing].discount.category_id → [product].category.id

折扣也可以綁定到商品分類。

[marketing].discount.brand_id → [product].brand.id

品牌折扣。

[marketing].promo_usage.user_id → [user].account.id

只有註冊用戶才能用優惠碼。

[marketing].featured_product.product_id → [product].product.id

首頁精選商品必須存在。

[marketing].referral_use.referrer_id → [user].account.id

邀請人一定要是用戶。

[marketing].referral_use.referee_id → [user].account.id

被邀請的人也是必須的用戶。

support schema:

[support].support_ticket.user_id → [user].account.id

每個客服單都是用戶創的。

[support].support_ticket.category_id → [support].ticket_category.id

客服單的分類可以被刪掉,單子還會留著。

[support].ticket_message.sender_id → [user].account.id

訊息是用戶(或 agent,如果他們也在 user.account)發的。

[support].support_agent.user_id → [user].account.id

客服 agent 也是用戶。

[support].ticket_status_log.changed_by → [user].account.id

記錄誰改了狀態(用戶或員工)。

content schema:

[content].article.author_id → [user].account.id

文章是註冊用戶寫的。

[content].media.uploaded_by → [user].account.id

誰上傳的媒體檔案(可能被刪掉)。

[content].content_revision.author_id → [user].account.id

誰改的內容(可能被刪掉)。

備註

只要可以的話,建議用 ON DELETE SET NULL,這樣刪掉某個 entity 時,關聯資訊不會完全消失。

如果是用 "target_type/target_id" 這種方式連 entity(像 user.comment),SQL 層級沒辦法設 foreign key,這種關聯要靠應用程式層級自己控。

這份清單涵蓋了 SQL 層級基本資料完整性需要的主要跨 schema 關聯。

包含解決方案的檔案。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION