How to store a 2D array in a MYSQL row? - mysql

This might not even be possible to do. I have one table that contains items. (item_id, item_name, description, json for deserializing into an actual object)
My second table contains packages. (package_id,package_name,price,description,item_list(2D array))
The 2D array needs to match item_id values to quantities.
Normally, I would simply serialize a JSON array to the item list spot. I worry about item_id values being removed or changed though. I cannot use a foreign key to have a change "cascade" or "delete" child values. Is there a way to store a kind of sub-table in a mysql row?
Let me know if my problem description is not clear. I want to make sure it is followable for anyone else who is trying to find an answer. I might include some images later if it will help.
Solution: No, there isn't a way to store a 2D array in a MySQL row. You have to use a bridge table. Oh well, at least there is a solution. A solution always exists.

Well you can always store 2D array in a column of a database but there is a problem with it, i.e retrieving data from mysql you'll have to parse that column and that column of yours will contain multiple values. When you have a multivalued attribute in your table it must be migrated to another table to normalize your database design.
In your case you are looking at many-to-many relation ship i.e a package may have many items and an item may be taken by many packages. To solve many-to-many relation you have to introduce a new table usually called a Bridge table. that bridge table will take Primary Keys from both item and package tables as Foreign Keys. The reason you add this table is to remove redundancy and that is one of many things normalization is offering.

What you are looking for is called a many-to-many relationship. Usually you create an extra table that creates a map between the two tables. Here is one example:
Many-to-many relationships examples

I was able to store a 2D array as a JSON object by using the index of the second dimension as a key. Here's an example of a 12 x 4 array:
{"0": "[0,0,0,0,0,0,0,0,0,0]", "1": "[0,0,0,0,0,0,0,0,0,0]", "2": "[0,0,0,1,0,1,0,1,0,0]", "3": "[0,0,0,1,1,1,1,1,0,0]"}

Related

Inserting JSON data line by line into an SQL table

I have a JSON file that stores the information about a bunch of recipes, like cuisine, time, the ingredients, instructions, etc. I am supposed to transfer all the data to a MySQL table with the relevant headings.
The "ingredients" and the "instructions" are stored like this:
The instructions and ingredients have several "lines" , stored as a list.
How can we store the ingredients and instructions in a MySQL table, in a line by line format?
something like:
instructions
inst1
inst2
..
The JSON file was created using a python program using the beautiful soup module.
PS: I am very new to both SQL and JSON, so I unfortunately dont have anything to show under "what I tried"...Any help will be appreciated.
Rather than give you the exact answer, I'll give you the process I use to determine a database structure. You're using a relational database, so that's what I'll talk about. Its also good to have a naming convention, I've used CamelCase here but you can do whatever you want.
You mentioned you were using python but this answer is language agnostic.
You've chosen quite a complex example, but I'll assume you understand how to create a table, and use primary keys and foreign keys. If not, maybe you should do something simpler.
Step 1 - Figure out what the entities are
These are the real-life entities which need to represented as database tables. In this case, I'm seeing 4 entities;
Recipe
Keyword
Ingredient
Instruction
Each of these can have a table in MySql. Give them a Primary key which follows a naming convention.
Step 2 - figure out the relationships
It looks like keywords are shared between multiple recipes, so you'll a many to many relationship - this means there's going to be an extra table,
RecipeKeyword
This is just a link between Recipe and keyword to avoid redundancy. It has two foreign keys, RecipeId and KeywordId. At the moment its just a dumb object. In other situations like this, its common for an application to need information about a join - for example, who linked the two things together (consider users, permissions, and a join table with information on who granted the permission)
The other entities are one to many - each will need a foreign key, RecipeId
Step 3 - design each table
As well as having several lists, your Recipe object has some properties. These can be in its table. Most of them are strings in your data, although there are better ways to store things we can keep this simple.
The other entities just have a text field, from your screenshot, only the Recipe has properties.
For this system, you'll need to first insert all Recipe and Keyword objects. There is a common pattern in relational databases where in insert a record, and get its ID so you can insert more stuff which references it.
Step 4 - find a python mysql library
I don't know of one but google will help you find it. The documentation should include the basics of querying.
Step 5 - Insert your data
Here is some psudocode
FOR EACH recipe
INSERT the recipe, and get its ID
FOR EACH keyword
IF the keyword does not exist already
INSERT the new keyword and get its ID
INSERT a record into RecipeKeyword with RecipeId and KeywordId
FOR EACH ingredient
INSERT the ingredient, give it RecipeId as a foreign key
FOR EACH instruction
INSERT the instruction, give it RecipeId as a foreign key
That's it. From here you can select with joins - To form what we're seeing above, you might need to do 3 seperate queries and merge them together into a record object on the python side to reproduce the original structure.

Best database table design for a table with dependent column values

I would like know the best way of designing a table structure for dependent column values.
If i have a scenario like this this
if the status of the field is alive nothing to do
if the status is died some other column values are stored somehow.
What is the best way to handle this situation
whether to create table containing all columns ie 'Died in the hospital','Cause of death','Date of Death' and 'Please narrate the event' and let it be null when status is alive
or
to use seperate table for storing all the other attributes using Entity-attribute-value (EVA) concepts
in the above scenario signs and symptoms may be single, multiple or others with specification. how to store this .
what is the best way for performance and querying
either to provide 15 columns in single table and store null if no value or to store foreign key of symptoms in another table (in this strategy how to store other symptom description column).
In general, if you know what the columns are, you should include those in the table. So, a table with columns such as: died_in_hospital, cause_of_death, and so on seems like a reasonable solution.
Entity-attribute-value models are useful under two circumstances:
The attributes are not known and new ones are added over time.
The number of attributes is so large and sparsely populated that most columns would be NULL.
In your case, you know the attributes, so you should put them into a table as columns.
Entity-attribute-value models is the best method, it will be helpful in data filtering/searching. Keeping the columns in the base table itself is against Normalization rules.

Mysql, list of values in a column

I have a table that stores information about categories ('cats' let's say) and another table (say 'cars' meaning it stores infos about cars - a lame example, but that doesn't matter) that has a column called 'parent_cat_id' which should reference 'id' col in 'cats'.
Now comes the problem: any car from 'cars' could belong to more then one category.
There's an obvious, but very lame, solution: store in parent_cat_id a delimited list of numbers, but, if i apply that, I couldn't have any foreign key constraint and should jump into parsing these values. Although parsing isn't such a big deal, but I can't believe MySQL doesn't have anything pre-built.
Also it looks like selecting cars by category will involve some substring and other things.
Having no foreign key is a far bigger problem.
The only thing I was able to find is a 'SET' type, but it should be pre-defined what values it can store during database development, also it can have only 64 pre-defined values while there could be 100s of categories.
The normal way of modeling this kind of many-to-many relationship is to introduce a third table (a junction table) that holds information about relationships between items in the two other tables.
In your example you would have three tables:
Category
Cars
CarCategory which has foreign keys to both the primary keys in Category and Cars
This is pretty fundamental relational modeling and you might want to look at a nice tutorial or book to get further knowledge about the concepts.
Just as you recognize storing delimited lists of keys is a bad idea as it breaks the model.

MYSQL: Creating a list of integers (IDs) which can use foreign key constraints for each integer element?

I was wondering if there is a way to create a foreign key for a list of integers that responds on single integer elements of the list.
For example, I have an "exercises" table. On that table, I would like to maintain two related columns:
"exercisesID"
"relatedExerciseIDs"
However, "relatedExerciseIDs" is a VARCHAR containing comma-delimited "exerciseID"s. On a deletion of an exercise from the table, any exercises with the deleted "exerciseID" in their "relatedExerciseIDs" list should remove it.
Is this possible? How can I do this?
Thanks for your opinions! I would also be interested in using a column type other than a VARCHAR if shown possible =)
All column values should be atomic.
You should not have a list of anything you want to query inside a single value.
The way to relate exercises to other exercises is with a second table. It will have two columns, each holding an exercise ID, where both columns are a foreign reference the exercises table.
The only way to do that is either via a stored procedure or in your language of choice. When you delete the record, you would then have to do a LIKE query to find any record with the value in your delimited field. It's really not the best way to do things, and would be slow as hell since you can't index that field the way you need to.
Your absolute best bet would be to create another table to define the relationships between exercises, using just two exercise id fields (exercise_id, related_exercise_id).
You should read up on Database Normalization.

Super general database structure

Say I have a store that sells products that fall under various categories... and each category has associated properties... like a drill bit might have coating, diameter, helix angle, or whatever. The issue is that I'd like the user to be able to edit these properties. If I wasn't interested in having the user change the properties, and I was building the store for a certain set of categories, I'd have one table for drill bits, etc. Alternatively, I could just modify the schema online but that doesn't seem to be done very often (unless we're talking phpmyadmin or something), and plus that doesn't fit in well at all with the way models are coupled to tables.
In general, I'm interested in implementing a multi-table database structure with various datatypes (because diameter might be a decimal, coating would be a string/index into a table, etc), within mysql. Any idea how this might be done?
If I understand correctly what you're asking, an, admittedly hacky, solution would be to have a products table that has to related tables, product_properties and product_properties_lookup (or some better name) where product_properties_lookup has an entry for every possible property a product can have and where product_properties contains the value of a property as a string with the ID of the property and the ID of the product. You could then coerce the property value into whatever type you wanted. Not ideal, but I'm not sure what else to do short of adding individual columns to the DB for property types.
Just use the database. It does all of this already. For free. And fast. How is having a table of products point to a table of properties with data types any different from a table with columns? It's not. Save if you use the DBs tables you get to use SQL to query it in all sorts of neat, and efficient ways compared to your own (crosstabs suck in SQL dbs).
Get a new product, make a new table. No big deal. Get a new property, alter the table. If you have 1M products in that table, yea, it may be a slow update (depends on the DB). Do you have 1M products? I don't think WalMart has 1M products.
Building Databases on top of Databases is a silly thing. Just use the one that's there. It is putty in your hands. Mold it to your whim.
Create a Property table first. This will contain all properties. It should have (at minimum) a Name column and a Type column ('string', 'boolean', 'decimal', etc.). Note: Primary keys are implied for all these tables.
Next, create a CategoryProperty table. Here you will be able to assign properties to a category. It should have these columns: CategoryID, PropertyID. Both foreign keys.
Then, create a Category table. This describes the categories. It should have a Name column and possibly some other columns like Description.
Then, create a ProductCategory table. Here, you will assign the categories for each product. It should have these columns: CategoryID, ProductID. Both foreign keys.
Next, create a PropertyValue table. Here, you will "instantiate" the properties and give them values. Columns include ProductID, PropertyID, and PropertyValue. The primary key can consist of ProductID and PropertyID.
Finally, create a Product table that just describes each product with columns like Name, Price, etc.
Note how for each relationship there is a separate table. If you only want one category for each product, you can do away with the ProductCategory table and just put a CategoryID field in the Product table. Similarly, if you want each property to belong to only one category, you can put a PropertyID column in the Category table and get rid of the CategoryProperty table.
Lastly, you will not be able to verify the data type for each property since each property has a different type (and they are rows, not columns). So just make the PropertyValue column a string and then perform your validation either as a trigger, or in your application, by checking the Type column of the Property table for that property.
If you're using a recentish version of mysql (5.1.5 or greater) you can store your data as XML in the database. You can then query that data using thigns like this.
Suppose I have a table that contains some items and I have a widgetpack that contains numerous
widgets. I can get my total number of widgets:
SELECT SUM( EXTRACTVALUE( infoxml, '/info/widget_count/text()' ) ) as widget_count
WHERE product_type="widgetpack"
assuming the table has an infoxml column and each widgetpacks infxml column contain XML that looks like this
<info>
<widget_count>10</widget_count>
<!-- Any other unstructured info can go in here too -->
</info>
DB purists will cringe at this, and it is kinda hacky. But often its easier to keep all your unstructured data in one place.
Have a look at this database schema on DatabaseAnswers.org:
http://www.databaseanswers.org/data_models/products_and_generic_characteristics/index.htm
Maybe consider an Entity-Attribute-Value (EAV) approach (not for the whole model of course!).
Related questions
Entity Attribute Value Database vs. strict Relational Model Ecommerce question
Approach to generic database design
How do you build extensible data model