is this table any good for mysql? I wanted to make it flexible in the future for this type of data storage. With this table structure, you can’t use a PRIMARY KEY but an index …
Should I change the format of the table to have headers – Primary Key, Width, Length, Space, Coupling …
ID_NUM Param Value 1 Width 5e-081 1 Length 12 1 Space 5e-084 1 Coupling 1.511 1 Metal Layer M3-0 2 Width 5e-082 2 Length 1.38e-061 2 Space 5e-081 2 Coupling 1.5 2 Metal Layer M310
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
No, this is a bad design for a relational database. This is an example of the Entity-Attribute-Value design. It’s flexible, but it breaks most rules of what it means to be a relational database.
Before you descend into the EAV design as a solution for a flexible database, read this story: Bad CaRMa.
More specifically, some of the problems with EAV include:
- You don’t know what attributes exist for any given ID_NUM without querying for them.
- You can’t make any attribute mandatory, the equivalent of NOT NULL.
- You can’t use database constraints.
- You can’t use SQL data types; the
valuecolumn must be a long VARCHAR.
- Particularly in MySQL, each VARCHAR is stored on its own data page, so this is very wasteful.
Queries are also incredibly complex when you use the EAV design. Magento, an open-source ecommerce platform, uses EAV extensively, and many users say it’s very slow and hard to query if you need custom reports.
To be relational, you should store each different attribute in its own column, with its own name and an appropriate datatype.
I have written more about EAV in my presentation Practical Object-Oriented Models in SQL and in my blog post EAV FAIL, and in my book, SQL Antipatterns: Avoiding the Pitfalls of Database Programming.
What you suggest is called
EAV model (Entity–Attribute–Value)
It has several drawbacks like severe difficulties in enforcing referential integrity constraints. In addition, the queries you’ll have to come up with, will be a bit more complicated than with a normalized table as your second suggestion (table with columns:
Primary Key, Width, Length, Space, Coupling, etc).
So, for a simple project, do not use EAV model.
If your plans are for a more complex project and you want maximum flexibility, do not use EAV either. You should look into
6NF (6th Normal Form) which is even harder to implement and certainly not an easy task in MySQL. But if you succeed, you’ll have both goods: flexibility and normalization to the highest level (some people call “EAV” as “6NF done wrongly“).
In my experience this idea of storing fields row-wise needs to be considered extremely carefully – although it seems give many advantages it makes many common tasks much more difficult.
On the positive side: It is easily extensible without changes to the structure of the database and in some ways abstracts the details of the data storage.
On the negative side: You need to look at all the everyday things storing fields column-wise gives you automatically in the DBMS: Simple inner/outer joins, one statement inserts/updates, uniqueness, foreign keys and other db level constraint checking, simple filtering ad ordering of search results.
Consider in your architecture a query to return all items with MetalLayer=X and Width between y and z – results sorted by Coupling by length. This query is much harder for you to construct and much, much harder for the DBMS to execute than it would be using columns to store specific fields.
In the balance the only time I have used a structure like the one you suggest was in a context where random unstructured additional data needed to be added on an ad-hoc basis. In my opinion this would be a last resort strategy if there was no way I could make a more traditional table structure work.
A few things to consider here:
There is no single primary key. This can be overcome by making the primary key consist of two columns (like in the second example of Carl T)
The Param column is repeated and to normalize this you should look at the example of MGA.
Thirdly the “Metal layer” column is a string and not a float value like the others.
So best to go for a table def like this:
create table yourTable( ID int primary key, ParamId int not null, Width float, Length float, Space float, Coupling float, Metal_layer varchar(20), Foreign key(ParamID) references Param(ID), Value varchar(20) ) create table Param( ID int primary key, Name varchar(20) )
The main question you have to ask when creating a table specially for future use is how will this data be retrieved and what purpose it is having. Personally I always have a unique identifier usually an ID to the table.
Looking at you list do not seem to have anything that uniquely defines the entries so you will not be able to track duplicate entries nor uniquely retrieve a record.
If you want to keep this design you could create a composite primary key composed of the name and the param-value.
CREATE TABLE testtest ( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(100) NOT NULL, value number NOT NULL /*add other fields here*/ ); CREATE TABLE testtest ( name VARCHAR(100) NOT NULL, value int NOT NULL, /*add other fields here*/ primary key(name,value) );
Those create table example express the 2 above mentioned options.