商品、訂單、購物車和訂單商品快照的關係,初步瞭解成爲架構師的思想

導讀

最近見同事在作訂單和訂單材料快照這方面的業務,這其實就像淘寶上的商品,不過,這裏是材料商品了。它一共涉及到 五張表數據庫

  1. 材料表,材料的詳細信息
  2. 訂單表,用戶購買材料時的記錄表
  3. 購物車,待付款材料
  4. 用戶表,誰購買了材料
  5. 訂單材料快照表,這就是訂單和材料的快照

於是,這裏面就涉及到一對一的關係。架構

一對一的關係

雖然一對一的關係用的很少,但咱們有時也會設計這方面的數據表,不經常使用不表明不用。app

分表通常會使用一對一的關係,好比說用戶表和用戶擴展表。用戶表存儲用戶必填的信息,好比 帳號、性別、密碼、登陸時間、退出時間等。用戶擴展表就是用戶的擴展信息,好比愛好、暱稱等。用戶可填可不填的。數據若是都放在同一張表中運維人員會感受比較亂。運維

以下,是部分的用戶實體和用戶擴展實體的代碼:post

用戶表的部分數據

@Entity
@Table(name = "core_user")
public class User {
    
      /**
     * 用戶名,惟一
     */
    @NotEmpty(message = "用戶名不能爲空")
    @Column(length = 100, unique = true, nullable = false)
    private String username;
    
    /**
     * 密碼
     */
    @Column(nullable = false, length = 66)
    private String password;
    
      /**
     * 用戶擴展表
     */
    @OneToOne(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private UserExt userExt;
    
    。。。。
}

用戶擴展表的部分數據

@Entity
@Table(name = "core_user_ext")
public class UserExt implements Serializable {
 
    @OneToOne
    @PrimaryKeyJoinColumn
    private User user;

    /**
     * 自我介紹
     */
    @Lob
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "introduce", columnDefinition = "text")
    private String introduce;

    /**
     * 性別
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "gender", length = 20)
    private GenderEnum gender;


    /**
     * 暱稱
     */
    @Column(name = "nick_name", length = 66)
    private String nickName;


    /**
     * 真實姓名
     */
    @Column(name = "real_name", length = 100)
    private String realName;
    
    /**
     * 頭像
     */
    @ManyToOne
    @JoinColumn(name = "head_image")
    private Picture headImage;

    /**
     * 聯繫地址
     */
    @Column(name = "address", length = 200)
    private String address;

    /**
     * 郵政編碼
     */
    @Column(name = "postal_code")
    private String postalCode;

    @Column(name = "qq", length = 66)
    private String qq;

    /**
     * 身高
     */
    @Column(length = 3)
    private Integer height;

    /**
     * 喜歡的運動
     */
    @Column(name = "loved_sports", length = 255)
    private String lovedSports;

    /**
     * 喜歡的電影
     */
    @Column(name = "loved_movies", length = 255)
    private String lovedMovies;

    /**
     * 喜歡的音樂
     */
    @Column(name = "loved_musics", length = 255)
    private String lovedMusics;

    /**
     * 喜歡的食物
     */
    @Column(name = "loved_foods", length = 255)
    private String lovedFoods;

    /**
     * 喜歡的書
     */
    @Column(name = "loved_books", length = 255)
    private String lovedBooks;

    /**
     * 喜歡的遊戲
     */
    @Column(name = "loved_games", length = 255)
    private String lovedGames;
}

用戶擴展信息是用戶的輔助信息,它們適合一對一的關係。fetch

詳解客戶材料(商品)、用戶材料(商品)、訂單、購物車、用戶、和訂單商品快照

  • 用戶,是誰購買了這個商品,這是咱們須要知道的。
  • 材料商材料(材料商的商品),由於,咱們這個平臺主要是售賣裝修材料的,其分爲兩部分。一部分是材料商在平臺上掛出他們的材料,材料商下的經銷商購買材料。他們購買材料後,這就涉及另外一部分,即經銷商掛出他們的材料。這時才賣給用戶,於是,對於經銷商來講,還要有一個市場零售價。
  • 經銷商材料(經銷商的商品):正如上面所說,我是經銷商,從材料商那邊購買了產品,而後,在個人這部分平臺上售賣,此時,用戶從我這邊購買了,而後將其加入到購物車中。
  • 訂單,即爲咱們在購買裝修材料時所生成的一條購買記錄。
  • 購物車,即爲咱們已經選好了商品,暫時尚未進行付款,只是暫存起來,這也是一條記錄。等咱們付款的時候,就從購物車中付款了。
  • 訂單快照,好比咱們昨天購買的商品材料,其當時的零售價是25元,但今天就變成了40元。咱們拿到材料後,感受不大合適,因而,申請退還材料。此時咱們在網頁上看到的材料價格是40元,而咱們付款的時候是25元。商家是退給咱們多少錢呢?25元,仍是40元?固然,是25元,而不是40元。這25元存儲在哪裏呢?就是訂單快照表。咱們在付款的那一刻,不論是直接購買的付款,仍是從購物車中的購買,就會生成一條訂單材料快照表。快照表有哪些信息:一個購物車的外鍵,訂單的外鍵,裝修材料的中必須讓用戶知道的信息等。裝修材料從某種意義上來講,其也是一種一對一的關係,商品和快照找那個所存儲的主要的材料信息。

全部的信息,如如下代碼。不重要的或設計公司機密的信息,就不在這裏展現了。編碼


用戶表

這裏用戶能夠爲分材料商和經銷商,經過這個枚舉類CustomerTypeEnum肯定的。材料商和經銷商放在同一張表中,根據他們的類型,來確認是材料商和經銷商。hibernate

@Entity
@Table(name = "core_user")
public class User{

    /**
     * 用戶名,惟一
     */
    @NotEmpty(message = "用戶名不能爲空")
    @Column(length = 100, unique = true, nullable = false)
    private String username;

    /**
     * 密碼
     */
    @Column(nullable = false, length = 66)
    private String password;

    /**
     * 最近登陸ip
     */
    @Column(name = "last_login_ip", length = 64)
    private String lastLoginIP;
    
   。。。。

材料商材料

由於材料商是一個實體,咱們這裏只要關聯材料商的外鍵便可,並且仍是一對多的關係。由於,材料表中某一個材料商的記錄不止一條。其次,還要有材料類型,材料類型表是樹結構的,類型下面還有子類型。這裏也是一對多的關係。設計

public class Material extends BaseObj {

    /**
     * 所屬品類
     */
    @ManyToOne
    @JoinColumn(name = "material_category_id")
    private MaterialCategory materialCategory;

    /**
     * 名稱
     */
    private String name;

    /**
     * 供應商
     */
    @ManyToOne
    @JoinColumn(name = "supplier_id")
    private Supplier supplier;

    /**
     * 品牌
     */
    @ManyToOne
    @JoinColumn(name = "material_brand_id")
    private MaterialBrand materialBrand;

    /**
     * 成本價
     */
    @Column(name = "cost_price", precision = 12, scale = 2)
    private BigDecimal costPrice;

    /**
     * 零售價
     */
    @Column(name = "retail_price", precision = 12, scale = 2)
    private BigDecimal retailPrice;

    /**
     * 單位
     */
    @ManyToOne
    @JoinColumn(name = "unit_code")
    private DataDict unit;
    
    。。。
}

經銷商材料

經銷商從材料商那邊購買了材料,經銷商的材料即來源於材料這張表。於是,這個經銷商材料只要關聯材料表便可。同時,還要有確認經銷商是哪一個經銷商,於是,須要一個用戶的外鍵,即經銷商材料的全部者。經銷商有本身的訂價規則,他須要定義一個市場價。code

public class UserMaterial extends BaseObj {

    /**
     * 材料
     */
    @ManyToOne
    @JoinColumn(name = "material_id")
    private Material material;

    /**
     * 全部者
     */
    @ManyToOne
    @JoinColumn(name = "owner_id")
    private User owner;

    /**
     * 市場價
     */
    @Column(name = "market_price", precision = 12, scale = 2)
    private BigDecimal marketPrice;

   。。。
}

訂單

咱們從經銷商那邊購買了材料,此時,有條購買記錄,這就是訂單。誰發起的訂單,也就是說,誰購買的這個材料,於是,須要用戶的外鍵。

public class Order extends BaseObj {

    /**
     * 收貨地址
     */
    @ManyToOne
    @JoinColumn(name = "work_site_id")
    private WorkSite workSite;

    /**
     * 訂單編號
     */
    @Column(name = "order_no")
    private String orderNo;

    /**
     * 訂單狀態
     */
    @Enumerated(EnumType.STRING)
    private OrderStatusEnum status;

    /**
     * 訂單備註
     */
    @Column(name = "remark", columnDefinition = "longtext")
    private String remark;

    /**
     * 下單時間
     */
    @Column(name = "generate_time")
    private Date generateTime;

    /**
     * 提交時間
     */
    @Column(name = "submit_time")
    private Date submitTime;

    /**
     * 買家
     */
    @ManyToOne
    @JoinColumn(name = "buyer_id")
    private User buyer;

購物車

咱們已經選好了材料,但尚未確認付不付款,因而,先在購物車存着,想起來就付款。加入到購物車的材料是經銷商的材料,於是,購物車須要存儲經銷商的外鍵。同時,還要確認是誰加入的購物車,於是購物車須要用戶的外鍵。這都是一對多的關係。同時,須要確認,這個購物車是否被使用。

public class ShoppingCart extends BaseObj {

    /**
     * 用戶材料
     */
    @ManyToOne
    @JoinColumn(name = "user_material_id")
    private UserMaterial userMaterial;

    /**
     * 數量
     */
    @Column(name = "num", precision = 12, scale = 2)
    private Double num = 1.0;

    /**
     * 金額
     */
    @Column(name = "amount", precision = 12, scale = 2)
    private BigDecimal amount;

    /**
     * 全部者
     */
    @ManyToOne
    @JoinColumn(name = "owner_id")
    private User owner;

    /**
     * 是否被使用
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "is_used")
    private BooleanEnum isUsed = NO;
}

訂單材料快照表

這裏,咱們只要存儲訂單快照的id,而不是訂單快照的對象?爲何呢?首先,對於用戶來講,購買裝修材料時,這個購物車是不經常使用的,由於,他們一旦看中了,就會直接購買的。其次,若是咱們存儲的是對象,用戶每次加載購物車時,都要從數據庫中遍歷當前id的購物車的數據庫的字段值,而後經過hibernate的反射封裝到購物車的對象中。因此說呢,無疑是減緩了效率,這樣很差。

須要訂單的外鍵,訂單和訂單快照雖然是一對一的關係,一個訂單一個訂單快照。也就是說,當用戶生成訂單時,就會有個訂單快照。用戶查看其購買記錄(訂單記錄)的材料信息時,材料信息不是來源於用戶材料表,而是來源於用戶訂單快照表。還有,用戶退還材料時,經銷商要查看用戶當前購買的材料信息。這就用到了訂單材料快照表。

public class OrderMaterialSnapshot extends BaseObj {

    /**
     * 購物車id
     */
    @Column(name = "shopping_cart_id")
    private Long shoppingCartId;

    /**
     * 訂單
     */
    @ManyToOne
    @JoinColumn(name = "order_id")
    private Order order;

    /**
     * 狀態
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private OrderMaterialStatusEnum status;

    /**
     * 購買數量
     */
    @Column(name = "num", precision = 12, scale = 2)
    private Double num = 1.0;

    /**
     * 退貨數量
     */
    @Column(name = "refund_num")
    private Double refundNum = 0.0;

    /**
     * 購買總金額
     */
    @Column(name = "amount", precision = 12, scale = 2)
    private BigDecimal amount;

    /**
     * 接單時間
     */
    @Column(name = "receive_time")
    private Date receiveTime;

    /**
     * 發貨時間
     */
    @Column(name = "deliver_time")
    private Date deliverTime;

    /**
     * 收貨時間
     */
    @Column(name = "receipt_time")
    private Date receiptTime;

    /**
     * 所屬品類
     */
    @ManyToOne
    @JoinColumn(name = "material_category_id")
    private MaterialCategory materialCategory;

    /**
     * 名稱
     */
    private String name;

    /**
     * 品牌
     */
    @OneToOne
    @JoinColumn(name = "material_brand_id")
    private MaterialBrand materialBrand;

    /**
     * 型號
     */
    private String model;

    /**
     * 零售價
     */
    @Column(name = "retail_price", precision = 12, scale = 2)
    private BigDecimal retailPrice;

    /**
     * 會員單價(材料商零售價*會員折扣)
     */
    @Column(name = "vip_unit_price", precision = 12, scale = 2)
    private BigDecimal vipUnitprice;

    /**
     * 市場價
     */
    @Column(name = "market_price", precision = 12, scale = 2)
    private BigDecimal marketPrice;

    /**
     * 單位
     */
    @ManyToOne
    @JoinColumn(name = "unit_code")
    private DataDict unit;
    
    。。。

}

總結

要想稱爲優秀的架構師,首先參考別人的架構,畢竟,他山之石,能夠攻玉嗎!!!

再接再礪,致奮鬥的本身!!!

相關文章
相關標籤/搜索