Table Design for Multiple Option Foreign Keys - mysql

I'm trying to determine if this table structure is optimal for what i'm trying to achieve. Here is the current structure:
The option data table would have a many to 1 relationship with the option_field. Basically i'm trying to create a generic option system where you can create fields - the option data table relates the specific system entity (customer, user, package, service, customer package, customer service) using the corresponding fields. Customer Packages and Customer Services option data is defined when the customerid, customeraccountid and customeraccountpersonid have values as well as the packageid or serviceid.
the question i'm wondering is if it makes sense to have all those ID columns on the option_data record, or if it would make more sense to segment those out somehow. Ideally this option service would be generic enough that if i wanted to add more entity type options i would just have to add the corresponding ID field in the option_data table down the road. My only concern with this is that a good chunk of those id's will be null since not all option_data will ALWAYS use ALL the id fields in the option_data table.
hope this makes sense... not sure if this is the ideal table design for what i'm trying to acheive - please let me know if i can further clarify.

Related

How to store modifications without changing the original DB record

I'm building an app in which users can create entities that are stored in my Entity table with some caracteristics like "space_below" and "width". Users can also create their own groups of entities by choosing amongst everybody's entities. Once they picked someone else's entity, I want them to be able to modify some caracteristics like the "width" and save these modifications for their own group. What would be to best way to do that in my DB?
First approach
Each time a user do a modification, create a new record (almost a duplicate) in the Entity table and then only refer to this new entity from the group where it was change.
In this case, I would need to add a column to my Entity table to differentiate original entites from copied entites.
Second approach
In any scenario, I will have a junction table between the Group table and the Entity table. In this junction table, I could add a "modification" column in which I store a JSON with the modifications. Something like { space_below: '8', width: '200' }. If there is no modficiation, the value of the column will be null.
I think I prefer the second approach since the first one involves a lot of duplicated data in the Entity table, but might not be aware of other implications.

SQL Structure for several tables

I need to create a mySQL database that keeps information about vehicles. My instincts were to create one table with as many columns as I need, but then I read about the problems in doing so. After researching, I think I'm on the right track with the following structure:
Vehicles Database
Motorcycles Table
id|road|cruising|touring|
Cars Table
id|sedan|coupe|hatchback|
Colours Table
id|green|red|blue|black|silver|white|yellow|etc..
Make Table
id|ford|chevrolet|gm|toyota|bmw|etc..
Quadrant Table (1-4)
id|motorcycle|car|truck
So basically I have a table for the objects - cars, motorcycles, trucks - and then tables for the fields/properties - Colour, Make, etc. and then a table for the Quadrant the vehicle is seen in, with a value of 1-4 where each row is an instance of only one vehicle.
The problem I'm having is understanding where the primary and foreign keys need to be in order for me to be able to organize the data:
By each individual vehicle selected along with its fields
By quadrant, showing each vehicle and their respective fields
The user counting cars should be able to input the vehicle type, the field values and the quadrant it's seen in and the db gets populated - and then I need to call the data by quadrant to analyze the data.
I don't know if or how a JOIN statement will be used? How do I go about structuring this database to suit my needs?
FWIW, dba.stackexchange says basic SQL questions belong here, so I hope I'm in the right place.
Can you tell, what is your exact need for the database i.e what functionality you need.
I suggest tables like following:
1) Vehicle table:
id|type which might contain info like 1|Motorcycle, 2|Car
2) category table:
id(foreign key)|category|color which contain info like 1|touring|Black, 2|Car|Hatchback
3) Make table: (if you need to create another table)
id (foreign key to table 1)|Make
I have not understood the functionality of quadrant table but with these 3 table you can create views according to your needs and play around with it.
From my point of view:
I will create a table CarBrands, with columns Id, BrandName, Description, which will serve as a look up.
Then I will create another table Cars with Id, CarBrandId, ColorId (From Colors Table), Description, which is your table with user records.
Same with your other entities. I suggest you search about Entity Relationship Diagrams, a good way of helping you come up with a good design.
Also look at this old StackOverflow question, this will help you.

Database table setup: Multiple tables that serve the same purpose?

I need to setup a MySQL database for a bugtracker, that's paired with a changelog.
Therefore I essentially have three tables: product, version, problem, problem_solution. The reason I splitted problems and their solutions is that I want to be able to provide my users with a set of possible solutions.
Now I want to add attachments to each of these tables and manage them via the database as well. There should be pictures, PDFs, ... for each product, version and possibly for each problem and solution.
Would I rather
Create 4 attachment-tables (product_attachments, version_attachments, ...), or
Create one attachment-table and create a column stating what it is for?
If latter, how should I do it? I want to reference to the specific ID of the product, version, problem or solution using a foreign key. Should I then just create 4 columns, each of them with a foreign key and decide whether it's an attachment for a product, a version, ... depending on which of these columns is not NULL? Wouldn't this make my queries unnecessarily complex?
I say create one table, have its primary key available, and create another table of EAV type for multi-to-multi relation between attachments and other entities, with "value" corresponding to attachment ID, "entity" to foreign ID and "attribute" to a value out of a fixed set of product, version, problem, solution in any form you like (1,2,3,4?). This way the attachments will be stored in a table of id, blob structure, maybe with corresponding count column storing the amount of links in the relation table, so that an orphaned attachment could be detected and removed with ease.

A more efficient way to store data in MySQL using more than one table

I had one single table that had lots of problems. I was saving data separated by commas in some fields, and afterwards I wasn't able to search them. Then, after search the web and find a lot of solutions, I decided to separate some tables.
That one table I had, became 5 tables.
First table is called agendamentos_diarios, this is the table that I'm gonna be storing the schedules.
Second Table is the table is called tecnicos, and I'm storing the technicians names. Two fields, id (primary key) and the name (varchar).
Third table is called agendamento_tecnico. This is the table (link) I'm goona store the id of the first and the second table. Thats because there are some schedules that are gonna be attended by one or more technicians.
Forth table is called veiculos (vehicles). The id and the name of the vehicle (two fields).
Fith table is the link between the first and the vehicles table. Same thing. I'm gonna store the schedule id and the vehicle id.
I had an image that can explain better than I'm trying to say.
Am I doing it correctly? Is there a better way of storing data to MySQL?
I agree with #Strawberry about the ids, but normally it is the Hibernate mapping type that do this. If you are not using Hibernate to design your tables you should take the ID out from agendamento_tecnico and agendamento_veiculos. That way you garantee the unicity. If you don't wanna do that create a unique key on the FK fields on thoose tables.
I notice that you separate the vehicles table from your technicians. On your model the same vehicle can be in two different schedules at the same time (which doesn't make sense). It will be better if the vehicle was linked on agendamento_tecnico table which will turn to be agendamento_tecnico_veiculo.
Looking to your table I note (i'm brazilian) that you have a column called "servico" which, means service. Your schedule table is designed to only one service. What about on the same schedule you have more than one service? To solve this you can create a table services and create a m-n relationship with schedule. It will be easier to create some reports and have the services well separated on your database.
There is also a nome_cliente field which means the client for that schedule. It would be better if you have a cliente (client) table and link the schedule with an FK.
As said before, there is no right answer. You have to think about your problem and on the possible growing of it. Model a database properly will avoid lot of headache later.
Better is subjective, there's no right answer.
My natural instinct would be to break that schedule table up even more.
Looks like data about the technician and the client is duplicated.
There again you might have made a decisions to de-normalise for perfectly valid reasons.
Doubt you'll find anyone on here who disagrees with you not having comma separated fields though.
Where you call a halt to the changes is dependant on your circumstances now. Comma separated fields caused you an issue, you got rid of them. So what bit of where you are is causing you an issue now?
looks ok, especially if a first try
one comment: I would name PK/FK (ids) the same in all tables and not using 'id' as name (additionaly we use '#' or '_' as end char of primary / foreighn keys: example technicos.technico_ and agendamento_tecnico has fields agend_tech_ and technico_. But this is not common sense. It makes queries a bit more coplex (because you must fully qualify the fields), but make the databse schema mor readable (you know in the moment wich PK belong to wich FK)
other comment: the two assotiative (i never wrote that word before!) tables, joining technos and agendamento_tecnico have an own ID field, but they do not need that, because the two (primary/unique) keys of the two tables they join, are unique them selfes, so you can use them as PK for this tables like:
CREATE TABLE agendamento_tecnico (
technico_ int not null,
agend_tech_ int not null,
primary key(technico_,agend_tech_)
)

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