Handling versions - mysql

Currently I'm working on a website for a client, who deals in software plugins. The client needs to be able to upload Products, and for these products different Versions, Updates and Patches. For example: veProduct v1.1.4 is Version 1, Update 1 and Patch 4 of the Product veProduct. Customers need to be able to buy a License to a Version. The License is a file that's generated per user, wich needs to be available for download. Currently I'm designing the database for the website, and I stumbled into a problem. How should I handle the different patches & versions?
My current Design:
In this design I created a table Product, which contains the information of the product itself, like the name and the description. Of the Product there can be multiple versions, which require different licenses, so I created another table called Version. In this table there will be a download-link, a changelog and the pricing of this version of the product. Also a discount price for customers who own the license of an older version, but that's not important. After this I created the User table, so that I could link the user and the version in the table License. In this table you can also find the download link to the license file.
After this, my trouble starts. I created the table Update, which is for example v2.3. This means it's version_id is 2 and it's update_id is 3. Then I created the table Patch, which could be for example v2.3.1, where version_id is 2, update_id is 3 and patch_id is 1. Until now there's no problem, but there's one big flaw in this design. That's when I want to upload a patch for a version that has no updates yet, like v1.0.1. That means I have to create a record in the table update, with the update_id 0 and no download link or changelog. I don't want to create a record without any purpose but to be a patches 'parent'.
[deleted]
Fixing my problem:
I find it hard to think of a solution, so I ask your help.
Would it be a good idea to get rid of the download-link fields in the version and update table and rely on the ones in the patch table? This way I would always make another patch, even if I only upload a newer version, or if I upload a completely new product. It just feels wrong to have the update table, only for being a patches parent.
So, can anyone help me figure this one out? How should I store new products, versions, updates and patches in my database. Where should I store my download-links? And last, but not least, how can I keep my version linked to the customer, and to the download-link for the license? (So every user gets his own license per version of a product, not per product, update or patch)
Sincerly,
Scuba Kay
PS: It really sucks not being able to post pictures if you're a new user, 'cause I'd like to post a screenshot of my MySQL Workbench instead of a bulk of code.

Instead of Update and Patch, why not just have a Release table that looks like this:
release_id,
version_id, --foreign key
type, -- this is either UPDATE or PATCH
release_name, -- this is the full ver number 1.0.1, for instances
changelog,
download_link
This would allow you to keep version so you can associate that with customer for licensing purposes but would let you be flexible about what you create first (updates or patches) without having to insert dummy rows.
BTW: In this model, I'd remove the download link from Version so it only exists at the release level (essentially release 1.0.0).

Related

Need optimized sql advice

So i have this database full of tables like suppliers, clients, stores, store_users, services(of each store), repairs, etc etc (a database of a IT brand that repairs computers at each store).
In the "repairs" table i have fields regarding the client, hardware, breakdown, condition and state of the repair("started", "waiting for client answer", "delivered" and others).
Everytime there are changes in the repair, for example: user1 received the repair order and inserted the repair into the system. user2 tested harddisk, RAM, etc for problems, found major disk problem so it needs to be replaced.
This information will change many fields in the "repair" but i need something like another table "interventions" to know what changed and who did what in each time there was an edit to the repair.
The only idea i had was to make a new table "interventions" with all the fields from the "repairs" table and every time someone edited the repair it would copy it to the intervention with a id_repair and a id_user linked.
PS: Users are the store's employees
It sounds like your "repair" table needs to be renamed to "interventions" and what you currently see as the "repair" table changed to a view which shows the most recent intervention.

How to approach dilemma: export orders from old magento system import into new magento, overlapping IDs

During an upgrade from Magento 1.5 to 1.7 unfortunately we had to reinstall Magento (don't ask) and now I need to get all of the old order information into the live upgrade. I've researched several scenarios. First would be identifying the tables in the database they correspond to and migrating those tables over, but I have three issues with that. One: I already did a little bit of that and because of the discrepancies between 1.5 and 1.7 caused several hours of debugging fun. Two: I can't figure out specifically which of these freaking tables needs updating (was going to just replace all sales_ tables). Third: since the upgrade other orders have been placed, and as you know, started order ids all over again and I don't want those entries to get replaced.
My other choice is to attempt to build an extension like this one: http://www.magentocommerce.com/magento-connect/dataflow-batch-import-export-orders-to-csv-xml.html. I already started but alas am already stuck on the oAuth process.
Before I waste anymore time, I'd like some advice. What would be the best way to go about this process?
Update 1-17
I have tried UNION queries on applicable tables but of course I get error "#1062 - Duplicate entry '1' for key 'PRIMARY'" being there are several primary keys. Is there a query to increment those primary keys of the new orders to follow after the ids of the old orders? I tried to do this in individual columns via UPDATE sales_flat_invoice_grid
SET increment_id = (increment_id+6150) or similar, but the ids are mapped to the ids on other tables! Please help! I'm afraid I'm going to have to tell boss that we need to buy that extension.
Continued from comment above ^^
hmmm .. If that's the case, the way I've done exports/imports in the past (see my post HERE) is use MySQL Workbench EER Modeling tool to create myself a diagram of the order storage system. I would select only one table at first, then MySQL will tell you what other tables are tied to that table. I repeat this process so that in my EER diagram, I don't have unnecessary tables, and I am not missing tables. I end up with exactly the number of tables I need to understand the flow.
Next, do the same for your 1.7 setup ... And compare. You will need to generate a SQL query that will not only INSERT the 1.5 orders into the 1.7 database, but you may need to create your own link table in case there is an ID that is used, you may need to link X to Y by way of Z. It's messy, and a little confusing, but I spent 3 weeks writing a SQL/PHP script that pulled 1) Product Data, 2) Category Data, 3) Customer Data and 4) Order Data. I also wrote one for Admin backend users and preferences. This was before I discovered the aforementioned tool.
EDIT I might add , that extension is only $200.00. How much in development time is it going to cost your employer for you to develop your way out of this? Depending on your hourly cost (I know with what I charge, $200 would be a steal) it may make more sense to get the extension.

MySQL: how to do row-level security (like Oracle's Virtual Private Database)?

Say that I have vendors selling various products. So, at a basic level, I will have the following tables: vendor, product, vendor_product.
If vendor-1 adds Widget 1 to the product table, I want only vendor-1 to see that information (because that information is "owned" by vendor-1). Same goes for vendor-2. Say vendor-2 adds Widget 2, only vendor-2 should see that information.
If vendor-1 tries to add Widget 2, which was already entered by vendor-2, a duplicate entry for Widget 2 should not be made in the product table. This means that, somehow, I need to know that vendor-2 now also "owns" Widget 2.
A problem with having multiple "owners" of a piece of information is how to deal owners editing/deleting the data. Perhaps vendor-1 no longer wants Widget 2 to be available to him/her, but that doesn't necessarily apply for vendor-2.
Finally, I want the ability to flag(?) certain records as "yes, I have reviewed this data and it is correct" such that it then becomes available to all the vendors. Say I flag Widget 1 as good data, that product should now be seen by all vendors.
It seems that the solution is row level security. The problem is that I'm not too familiar with its concepts or how to implement it in MySQL. Any help is highly appreciated. Thanks.
NOTE: this problem is somewhat discussed here: Database Design: use composite key as FK, flag data for sharing?. When I asked the question, I wasn't sure how to phrase the question very well. Hopefully, I explained my problem better this time.
Mysql doesn't natively support row level security on tables. However, you can sort of implement it with views. So, just create a view on your table that exposes only the rows you want a given client to see. Then, only provide that client access to those views, and not the underlying tables.
See http://www.sqlmaestro.com/resources/all/row_level_security_mysql/
You already suggested a vendor, product and vendor_product mapping table. You want vendors to share the same product if they both want to use it, but you don't want duplicate products. Right?
If so, then define a unique index/constraint on the natural key that identifies a product (product name?).
If a vendor adds a product, and it doesn't exist, insert it into the product table, and map it to that vendor via the vendor_product table.
If the product already exists, but is mapped to another vendor, do not insert anything into the product table, and add another mapping row mapping the new vendor to the existing product (so that now the product is mapped to two vendors).
Finally, when a vendor removes a product, instead of actually removing it, just delete the vendor_product reference mapping the two. Finally, if no other vendors are still referencing a product, you can remove the product. Alternatively, you could run a script periodically that deletes all products that no longer have vendors referencing them.
Finally, have a flag on the product table that says that you've reviewed the product, and then use something like this to query for products viewable by a given vendor (we'll say vendor id 7):
select product.*
from product
left join vendor_map
on vendor_map.product_id = product.product_id
where vendor_map.vendor_id = 7
or product.reviewed = 1;
Finally, if a product is owned by multiple vendors, then you can either disallow edits or perhaps "split" the single product into a new unique product when one of the owning vendors tries to edit it, and allow them to edit their own copy of the product. They would likely need to modify the product name though, unless you come up with some other natural key to base your unique constraint on.
This sounds to me that you want to normalize your data. What you have is a 1 (product) to many (vendors) relationship. That the relationship is 1:1 for most cases and only 1:n for some doesn't really matter I would say - in general terms it's still 1:n and therefor you should design your database this way. The basic layout would probably be this:
Vendor Table
VendorId VendorName OtherVendorRelatedInformation
WidgetTable
WidgetId WidgetName WidgetFlag CreatorVendor OtherWidgetInformation
WidgetOwnerships
VendorId WidgetId OwnershipStatus OtherInformation
Update: The question of who is allowed to do what is a business problem so you need to have all the rules laid out. In the above structure you can flag which vendor created the widget. And in the ownership you can flag what the status of the ownership is, for example
CreatorFullOwnership
SharedOwnership
...
You would have to make up the flags based on your business rules and then design the business logic and data access part accordingly.

how to allow orphan recordsets in many-to-many bridge tables

I have a problem that I can't seem to solve.
I have table: Software
and table: PC
they both have many to many relationship between each other, that is, one PC can have many Software and One Software can have many PC's
the link table is: soft-pc
The table soft-pc also has licensing information like, product keys.
now the problem is, when a software is deleted from a PC the record is deleted from the soft-pc table. Now I want to be able to un-associate software from PC and still have them in soft-pc table.
Is that possible?
Now I want to be able to un-associate software from PC and still have them in soft-pc table.
This is the core of the problem. At the moment, the relation predicate for the soft-pc table - that is, what it means for there to be a particular record in this table - is that the software in question is on the PC in question. If you now want to say that it's possible for there to be a record in this table when there isn't that software on that PC, you are going to have to decide what the new relation predicate is. Which is to say:
What does it mean for there to be a record in the soft-pc table?
You will need to remove cascading deletes from the relationship, after that, two possibilities occur to me:
Add a deleted date to soft PC
Move the PC ID to another column - this will only work if the unique key is not PCID + Soft ID.
I would be inclined to go with #1.
EDIT re additional post
If you wish, you can have a junction table with all possible PC-Soft combinations and a code to indicate whether or not the software is installed, uninstalled, never-to be-installed etc, and a date at which the status occurred. There is a lot to be said for this approach.

Inventory Architecture in Database

This is not a question related to a specific language, rather on the correct methodology of architectural of handling inventory.
Consider the following structure for storing software:
platforms (platformID*, platformName)
titles (titleID*, titleName)
And the following is a joiner table for unique products
products (platformID*, titleID*, releaseDate, notes)
And the following is a table I would like to keep track of my inventory
inventory (platformID*, titleID*, quantityAvailable)
In examples I have seen, others have created a table where each unique copy of a software is stored in a separate line as such:
software(softwareID*, softwareTitle)
inventory(inventoryID*, softwareID*)
I would like to know which approach is preferable? Should I create an inventoryID and thus a row for each unique software copy:
inventory(inventoryID*, platformID*(fk), titleID*(fk))
Or use a table that stores quantity instead, as such:
inventory(platformID*(fk), titleID*(fk), quantityAvailable)
The advantage of having a unique row for each piece of inventory is that later if you want to keep track of things like inventory that's on layover, inventory that's on preorder, inventory that's been sold but could still be returned, etc.
I don't see any real disadvantage to this approach except that it's probably more work which might not pay off if these things aren't really needed.
I also would start with quantityAvailable instead of lines for all the items. But I would still opt for an inventoryId, since cases could occur, where you have to dissect the entries with the same platform/title combination -- with an inventoryId you are more enhanceable in the future.
I would also recommend to add a further column: versionNo --- the version number of a software product. Sometimes you might have differing versions of the same product. When you have this, it is not a good idea to drop the information into the title (for example you want to search for all "Microsoft Office" products regardless of version ...).
Should I create an inventoryID and
thus a row for each unique software
copy?
There is no reason to do this, unless you want to store some information on each unique software copy, such as the date each copy was purchased. This is rarely pracitical in the inventory of software.
Or use a table that stores quantity
instead?
You can also consider adding a quantityAvailable column in your products table, unless you think that eventually you'd want to have many inventories for each title, in order to be able to allocate a quantity of stock that is under special offer, that is soon going to expire, etc.