Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic mysql versioning?

We have a shopping cart as pictured below, The setup works well, except for one fatal flaw. If you place an order the order is linked to a product, so If I update the product after you have purchased the product there is no way for me to show you want the product looked like when you bought it (including price). This means we need versioning.

Current Schema

My plan at present is to, when a new product, or variant is created, or an existing one is edited, create a duplicate of the product or variant in the database. When a purchase is made, link the order to the version, not the product.

This seems rather simple, except from what I can see the only things we don't need to version are the categories (as no one cares what categories it was in.). So we need to version:

  • Products
  • Variants
  • The key -> value pairs of attributes for each version
  • The images

My current thinking is,

note: When a product is created a default variant is created as well, this cannot be removed.

  • When a product is created
    • Insert the product into the products table.
    • Create the default variant
    • Duplicate the product into the products_versions table
      • Replace current id column with a product_id column
      • Add id column
    • Duplicate the variant into the variants_versions table
      • Replace current id column with variant_id column
      • Add id column
      • Replace product_id column with product_version_id column

  • When a product is edited
    • Update the product into the products table.
    • Duplicate the product into the products_versions table
      • Replace current id column with a product_id column
      • Add id column
    • Duplicate all product variants into the variants_versions table
      • Replace current id column with variant_id column
      • Add id column
      • Replace product_id column with product_version_id column
    • Duplicate all variant_image_links into the variant_Image_link_version table
      • Replace current variant_id column with variant_version_id column

  • When a variant is added
    • Add the variant into the variants table.
    • Duplicate the product into the products_versions table
      • Replace current id column with a product_id column
      • Add id column
    • Duplicate all product variants into the variants_versions table
      • Replace current id column with variant_id column
      • Add id column
      • Replace product_id column with product_version_id column

  • When a variant is edited
    • Update the variant in the variants table.
    • Duplicate the product into the products_versions table
      • Replace current id column with a product_id column
      • Add id column
    • Duplicate all product variants into the variants_versions table
      • Replace current id column with variant_id column
      • Add id column
      • Replace product_id column with product_version_id column
    • Duplicate all variant_image_links into the variant_Image_link_version table
      • Replace current variant_id column with variant_version_id column

So the final structure looks like Full Size

Now this all seems great, except it seems like a heck of a lot of duplicated data, e.g. if we update a product we duplicate the variants even though they would not have been updated since they were inserted. Also, this seems like a lot of work.

Is there a better way of doing this?

like image 759
Hailwood Avatar asked Nov 13 '12 12:11

Hailwood


People also ask

Which version of MySQL should I use?

If you ran some performance tests on a development server that indicates you are getting near your limit, you could try 5.5 to see if that helps any. For future projects, I would definitely recommend 5.5, however. Save this answer.

What is SQL versioning?

Versioning a database means sharing all changes of a database that are neccessary for other team members in order to get the project running properly. Database versioning starts with a settled database schema (skeleton) and optionally with some data.

What is the current version of MySQL?

MySQL Server 8.0. 37, new versions of the popular Open Source Database Management System, have been released in conjunction with the 8.0.


1 Answers

You can do what ERP (and also possibly Payroll) systems do: Add a Start and End Date/Time. So...

  • the variant and prices match with their product based on the common dates.
  • all queries default to running on current date and the joins between each table need to also take into account the overlapping/intersecting date ranges. parent_start_date <= child_start_date AND parent_end_date >= child_end_date
  • You would end up with duplicated rows for each price change or variant but you then don't need to keep update as many records (like variant ids) when the product price changes.
  • Need to ensure valid dates are used. PS: Use your system's max date for the End datetime of the most current/recent record.

Btw, some related questions along the same line:

  • Ways to implement data versioning in MongoDB
  • Ways to implement data versioning in PostreSQL
  • Ways to implement data versioning in Cassandra
  • Row versioning in MySQL
like image 94
aneroid Avatar answered Sep 29 '22 16:09

aneroid