基本的mysql版本控制?

时间:2012-11-13 12:56:56

标签: mysql database database-design versioning database-versioning

我们有一个购物车,如下图所示,设置运行良好,除了一个致命的缺陷。如果您下订单该订单与产品相关联,那么如果我在您购买产品后更新产品,我就无法向您展示您希望产品在购买时的样子(包括价格)。这意味着我们需要版本控制。

Current Schema

我目前的计划是,在创建新产品或变体或编辑现有产品或变体时,在数据库中创建产品或变体的副本。购买时,将订单链接到版本,而不是产品。

这似乎相当简单,除了我可以看到的,我们不需要版本的唯一内容是类别(因为没有人关心它的类别)。所以我们需要版本:

  • 产品
  • 变体
  • 密钥 - >每个版本的值属性对
  • 图片

我目前的想法是,

  

注意: 创建产品时,也会创建默认变体,但无法将其删除。

  • 创建产品时
    • 将产品插入产品表。
    • 创建默认变体
    • 将产品复制到products_versions表中
      • 使用product_id列替换当前id列
      • 添加ID列
    • 将变体复制到variants_versions表中
      • 将当前id列替换为variant_id列
      • 添加ID列
      • 将product_id列替换为product_version_id列

  • 编辑产品时
    • 将产品更新到产品表中。
    • 将产品复制到products_versions表中
      • 使用product_id列替换当前id列
      • 添加ID列
    • 将所有产品变体复制到variants_versions表中
      • 将当前id列替换为variant_id列
      • 添加ID列
      • 将product_id列替换为product_version_id列
    • 将所有variant_image_links复制到variant_Image_link_version表中
      • 将当前variant_id列替换为variant_version_id列

  • 添加变体时
    • 将变体添加到变体表中。
    • 将产品复制到products_versions表中
      • 使用product_id列替换当前id列
      • 添加ID列
    • 将所有产品变体复制到variants_versions表中
      • 将当前id列替换为variant_id列
      • 添加ID列
      • 将product_id列替换为product_version_id列

  • 编辑变体时
    • 更新变体表中的变体。
    • 将产品复制到products_versions表中
      • 使用product_id列替换当前id列
      • 添加ID列
    • 将所有产品变体复制到variants_versions表中
      • 将当前id列替换为variant_id列
      • 添加ID列
      • 将product_id列替换为product_version_id列
    • 将所有variant_image_links复制到variant_Image_link_version表中
      • 将当前variant_id列替换为variant_version_id列

所以最终结构看起来像Full Size

现在这一切看起来都很棒,除了它看起来像是一堆重复的数据,例如如果我们更新产品,我们会复制变体,即使它们在插入后也没有更新过。此外,这似乎是很多工作。

有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

您可以执行ERP(以及可能还有Payroll)系统的操作:添加开始和结束日期/时间。所以......

  • 变量和价格根据常见日期与其产品匹配。
  • 所有查询默认在当前日期运行,每个表之间的连接也需要考虑重叠/相交日期范围。 parent_start_date <= child_start_date AND parent_end_date >= child_end_date
  • 对于每个价格变化或变体,您最终会得到重复的行,但是当产品价格发生变化时,您不需要保持更新记录(如变量ID)。
  • 需要确保使用有效日期。 PS:使用系统的最大日期作为最新/最近记录的结束日期时间。
顺便说一下,同一条线上的一些相关问题:

答案 1 :(得分:0)

另一种方法是永远不要编辑或删除数据,只创建新数据。在SQL术语中,您在表上运行的唯一操作是INSERT和SELECT。

要完成您想要的任务,每个表都需要以下列:

  • version_id - 这将是您的主键
  • id - 这就是将对象的版本保存在一起的东西(例如,查找产品的所有版本,SELECT * FROM产品WHERE id =?)
  • CREATION_DATE
  • is_active - 你没有删除任何内容,所以你需要标记(逻辑上)删除数据

有了这个,这就是你的产品表的样子:

CREATE TABLE products (
  version_id CHAR(8) NOT NULL PRIMARY KEY,
  id INTEGER NOT NULL,
  creation_date TIMESTAMP NOT NULL DEFAULT NOW(),
  is_active BOOLEAN DEFAULT true,
  name VARCHAR(1024) NOT NULL,
  price INTEGER NOT NULL
);

CREATE TABLE variants (
  version_id CHAR(8) NOT NULL PRIMARY KEY,
  id INTEGER NOT NULL,
  creation_date TIMESTAMP NOT NULL DEFAULT NOW(),
  is_active BOOLEAN DEFAULT true,
  product_version_id CHAR(8) NOT NULL,
  price INTEGER NOT NULL,
  override_price INTEGER NOT NULL,
  FOREIGN KEY (product_version_id) REFERENCES products(version_id)
);

现在,要插入任何一个表

  1. 生成一个唯一的version_id(有几种策略,一种是使用数据库序列,或者是MySQL使用ant AUTO_INCREMENT)。
  2. 生成ID。此ID对于产品的所有版本都是一致的。
  3. 要更新表格中的行,必须插入整个图表,例如要更新产品,必须插入新产品和新变体。 (这里有很多优化空间,但最简单的方法是从未优化的解决方案开始。)

    例如,更新产品

    1. 生成唯一的version_id
    2. 使用相同的ID
    3. 插入新产品变体。变体将与您正在“更新”的产品的先前版本链接的变体相同,但product_version_id将不同。
    4. 此主体可以扩展到您的所有表格。

      要查找产品的最新版本,您需要使用creation_date列来获取最近创建的产品。

      这个模型将使用更多的空间,但我认为这可能是一个公平的权衡,因为它很简单:只有INSERT和SELECT,数据永远不会发生变异。