mysql table structure proposal?

99封情书 提交于 2019-11-30 05:30:20

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 value column 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!