2011-11-29 13 views
8

questa tabella è utile per MySQL? Volevo renderlo flessibile in futuro per questo tipo di archiviazione dei dati. Con questa struttura della tabella, non è possibile utilizzare una chiave primaria, ma un indice ...Proposta di struttura della tabella mysql?

Devo cambiare il formato della tabella di avere le intestazioni - Chiave primaria, larghezza, lunghezza, Spazio, accoppiamento ...

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 
+1

Shef, che avrebbe funzionato, ma non essere normalizzato. – nageeb

+0

ho pensato che la chiave primaria debba essere unica? – Gordon

+1

Questo non può essere normalizzato perché non è una relazione. –

risposta

10

No, questo è un cattivo progetto per un database relazionale. Questo è un esempio del design Entity-Attribute-Value. È flessibile, ma infrange la maggior parte delle regole su cosa significhi essere un database relazionale.

Prima di scendere nel progetto EAV come soluzione per un database flessibile, leggere questa storia: Bad CaRMa.

In particolare, alcuni dei problemi con EAV includono:

  • Tu non sai quali attributi esistono per qualsiasi ID_NUM senza interrogare per loro.
  • Non è possibile rendere obbligatorio alcun attributo, l'equivalente di NOT NULL.
  • Non è possibile utilizzare i vincoli del database.
  • Non è possibile utilizzare tipi di dati SQL; la colonna value deve essere un VARCHAR lungo.
  • In particolare in MySQL, ogni VARCHAR è memorizzato nella propria pagina di dati, quindi questo è molto dispendioso.

Le query sono anche incredibilmente complesse quando si utilizza il design EAV. Magento, una piattaforma di e-commerce open source, utilizza EAV ampiamente e molti utenti dicono che è molto lento e difficile da interrogare se hai bisogno di report personalizzati.

Per essere relazionali, è necessario memorizzare ogni attributo diverso nella propria colonna, con il proprio nome e un tipo di dati appropriato.

Ho scritto altro su EAV nella mia presentazione Practical Object-Oriented Models in SQL e nel mio post del blog EAV FAIL e nel mio libro, SQL Antipatterns: Avoiding the Pitfalls of Database Programming.

+0

+1 Sintesi eccellente dei problemi – Elemental

0

La domanda principale che devi porre quando crei una tabella appositamente per un utilizzo futuro è come verranno recuperati questi dati e quale scopo sta avendo. Personalmente ho sempre un identificatore univoco di solito un ID al tavolo.

Guardando l'elenco non sembra avere nulla che definisce in modo univoco le voci in modo da non essere in grado di tracciare le voci duplicate né recuperare in modo univoco un record.

Se si desidera mantenere questo disegno, è possibile creare una chiave primaria composta composta dal nome e dal valore param.

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) 
); 

Quelli che creano l'esempio di tabella esprimono le 2 opzioni sopra menzionate.

1

Secondo la mia esperienza, questa idea di immagazzinare i campi in fila deve essere considerata con estrema attenzione - sebbene sembri dare molti vantaggi rende molto più difficili molti compiti comuni.

Sul lato positivo: è facilmente estendibile senza modifiche alla struttura del database e in qualche modo astrae i dettagli dell'archiviazione dei dati.

Sul lato negativo: è necessario esaminare tutte le cose quotidiane che memorizzano i campi in base alle colonne nel DBMS: semplici join interni/esterni, una istruzione inserimenti/aggiornamenti, univocità, chiavi esterne e altro livello db controllo dei vincoli, semplice filtraggio dell'ordine degli annunci dei risultati di ricerca.

Considerare nella propria architettura una query per restituire tutti gli elementi con MetalLayer = X e Larghezza tra y e z - i risultati sono ordinati per Accoppiamento per lunghezza. Questa query è molto più difficile da costruire per te e molto, molto più difficile da eseguire per il DBMS di quanto non sarebbe usare le colonne per memorizzare campi specifici.

Nella bilancia l'unica volta che ho utilizzato una struttura come quella che suggerisci era in un contesto in cui i dati aggiuntivi non strutturati casuali dovevano essere aggiunti su una base ad-hoc. A mio parere, questa sarebbe una strategia di ultima istanza se non potessi realizzare una struttura di tavoli più tradizionale.

1

Quello che proponiamo è chiamato EAV model (Entity–Attribute–Value)

Esso ha diversi svantaggi come gravi difficoltà nel far rispettare vincoli di integrità referenziale. Inoltre, le query che dovrai fornire saranno un po 'più complicate rispetto a una tabella normalizzata come secondo suggerimento (tabella con colonne: Primary Key, Width, Length, Space, Coupling, etc).

Quindi, per un progetto semplice, non utilizzare il modello EAV.

Se i piani sono per un progetto più complesso e si desidera la massima flessibilità, non utilizzare nemmeno EAV. Dovresti esaminare 6NF (6th Normal Form) che è ancora più difficile da implementare e sicuramente non è un compito facile in MySQL.Ma se ci riesci, avrai entrambi i prodotti: flessibilità e normalizzazione al massimo livello (alcune persone chiamano "EAV" come "6NF fatto erroneamente").

1

Alcune cose da considerare qui:

Non c'è una singola chiave primaria. Questo può essere risolto rendendo la chiave primaria costituita da due colonne (come nel secondo esempio di Carl T)

La colonna Param viene ripetuta e per normalizzare questo si dovrebbe guardare l'esempio di MGA.

In terzo luogo, la colonna "Metal layer" è una stringa e non un valore float come gli altri.

Quindi meglio andare per un def tabella come questa:

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) 
) 
Problemi correlati