Alanların dinamik sayıda MySQL tasarım

7 Cevap php

MySQL ile benim deneyim çok temel. Basit şeyler yeterince kolaydır, ama ben biraz daha bilgi gerektiren olacak bir şey koştu. Ben kelimelerin küçük bir listesini saklayan bir tablo için bir ihtiyaç var. Saklanan kelimelerin sayısı her yerde 1-15 arasında olabilir. Sonra, ben bu sözleri tarafından masaya aracılığıyla arıyor planlıyoruz. Ben bir kaç farklı yöntem düşündüm:

A.) Ben 15 alanları ile veritabanı oluşturmak ve veri 15'ten küçük olduğunda sadece null değerleri ile alanları doldurun olabilir. Bunun gibi gerçekten yok. Bu gerçekten verimsiz görünmektedir.

B.) Başka bir seçenek, sadece tek bir alan kullanın ve virgülle ayrılmış bir liste olarak veri depolamak için. Geri arama gel zaman, ben sadece sahada düzenli bir ifade çalıştırmak istiyorum. Yine, bu gerçekten verimsiz görünmektedir.

Ben bu iki seçenek için iyi bir alternatif olduğunu umut ediyorum. Herhangi bir tavsiye çok mutluluk duyacağız.

-Teşekkürler

7 Cevap

C) normal form kullanmak; Uygun tuşları ile birden fazla satır kullanabilirsiniz. Bir örnek:

mysql> SELECT * FROM blah;
+----+-----+-----------+
| K  | grp | name      |
+----+-----+-----------+
|  1 |   1 | foo       |
|  2 |   1 | bar       |
|  3 |   2 | hydrogen  |
|  4 |   4 | dasher    |
|  5 |   2 | helium    |
|  6 |   2 | lithium   |
|  7 |   4 | dancer    |
|  8 |   3 | winken    |
|  9 |   4 | prancer   |
| 10 |   2 | beryllium |
| 11 |   1 | baz       |
| 12 |   3 | blinken   |
| 13 |   4 | vixen     |
| 14 |   1 | quux      |
| 15 |   4 | comet     |
| 16 |   2 | boron     |
| 17 |   4 | cupid     |
| 18 |   4 | donner    |
| 19 |   4 | blitzen   |
| 20 |   3 | nod       |
| 21 |   4 | rudolph   |
+----+-----+-----------+
21 rows in set (0.00 sec)

Bu benim group_concat . You'll note that there is a unique key K her satır için yaklaşık bu diğer soru gönderdi tablodur. Her bir kategoriyi temsil eden başka bir anahtar grp vardır. Kalan alan bir kategori üyesini temsil ve kategori başına bu değişken numaralar olabilir.

Ne diğer veriler bu kelime ile ilişkili?

Bu tür sorunları işlemek için tipik bir şekilde en iyi örnek tarafından açıklanmıştır. Senin tablo bazı belgelerde bulunan bazı kelimeleri yakalar varsayalım. Tipik bir yol, her belgeyi bir tanımlayıcı atamak için. Birbirlerinin belge bir web URL, yani böyle bir tablo bir şey olurdu ki, şu an için, farz edelim:

CREATE TABLE WebPage (
    ID INTEGER NOT NULL,
    URL VARCHAR(...) NOT NULL
)

Your Words tablo şöyle görünebilir:

CREATE TABLE Words (
    Word VARCHAR(...) NOT NULL,
    DocumentID INTEGER NOT NULL 
)

Sonra, her bir kelime için, tabloda yeni bir satır oluşturun. Belirli bir belgedeki tüm kelimeleri bulmak için, belgenin kimliği tarafından seçin:

SELECT Words.Word FROM Words, WebPage 
WHERE Words.DocumentID = WebPage.DocumentID
AND WebPage.URL = 'http://whatever/web/page/'

Belirli bir kelime ile tüm belgeleri bulmak için, kelime seçin:

SELECT WebPage.URL FROM WebPage, Words
WHERE Words.Word = 'hello' AND Words.DocumentID = WebPage.DocumentID

Ya da böyle.

Hurpe, size bir 15 adede kadar anahtar kelimeleri içeren bir sütun ile bir veritabanı tablo var olacağı açıklayan senaryodur. Daha sonra muhtemelen de diğer sütunları olacak masa aramak için bu anahtar kelimeleri kullanacak?

Sonra anahtar kelimeler için ayrı bir tablo var cevap değil mi? Ayrıca anahtar kelimeler ve ana tablo arasında çok-çok ilişkisi olması gerekir.

Yani örnek olarak araba kullanırken, 15 ya da öylesine anahtar kelimeleriniz WORD tablo aşağıdaki yapıya sahip olacaktır:

ID             int
Word           varchar(100)

CAR tablo gibi bir yapı bir şey olurdu:

ID              int
Name            varchar(100)

Sonra nihayet çok-çok ilişkileri tutmak için bir CAR_WORD tablo gerekir:

ID              int
CAR_ID          int
WORD_ID         int

Ve örnek veriler WORD tablo için bu ile gitmek için:

ID   Word

001  Family
002  Sportscar
003  Sedan
004  Hatchback
005  Station-wagon
006  Two-door
007  Four-door
008  Diesel
009  Petrol

Birlikte CAR tablo için örnek veri ile

ID   Name

001  Audi TT
002  Audi A3
003  Audi A4

sonra kavşak CAR_WORD tablo örnek veri olabilir:

ID    CAR_ID   WORD_ID
001   001      002
002   001      006
003   001      009

Audi TT doğru özellikleri verecek olan.

ve nihayet aramak için SQL gibi bir şey olurdu:

SELECT c.name
FROM CAR c
INNER JOIN CAR_WORD x
ON c.id = x.id
INNER JOIN WORD w
ON x.id = w.id
WHERE w.word IN('Petrol', 'Two-door')

Vay! Oldukça çok yazmak için yola niyetinde değildi, bu karmaşık görünüyor ama ben hep sona görünmektedir nerede ancak sert bir şeyleri basitleştirmek için deneyin.

Ben ve kimliği ve bir alan bir tablo yaratacak, sonra birden fazla kayıtları gibi sonuçları saklayın. Bu pek çok avantajlar sunmaktadır. Örneğin, daha sonra programlama yerine tasarım bunu yapmanın 15 kelime sınırı zorlamak, böylece hiç fikrinizi değiştirirseniz oldukça kolay olmalıdır. Veri arama sorguları da çalıştırmak için çok daha hızlı olacak, düzenli ifadeler (nispeten) çalıştırmak için çok fazla zaman alır. Artı alan için bir varchar kullanarak size çok daha iyi bir tablo sıkıştırmak için izin verecektir. Ve masanın üzerine dizin bu tasarım ile (daha verimli) çok daha kolay olmalıdır.

Ekstra çalışma yapmak ve tablodaki 15 satır olarak 15 kelime saklamak, yani veri normalleştirmek. Bu sizin strateji biraz yeniden düşünmek gerek, ama müşteri boyunca gelir ve, sen yaptın memnuniyet duyarız "Eğer 20 15 sınırı ... değiştirebilir miyim" diyor bana güven olabilir.

Yapmak istediğiniz tam olarak ne bağlı olarak:

  1. Dizenizin masada bir tam metin dizini kullanın

  2. Üç tablo: orijinal dizesi için bir, eşsiz kelimeleri tek (kelime-köklenmesi sonra mı?), Ve bir birleşim tablo. Bu da ya "'tilki' köpek 'sonra gerçekleşen tüm dizeleri dönmek" "en azından aşağıdaki beş kelimelerin üçünü içeren tüm dizeleri dönmek" gibi, daha karmaşık arama yapalım istiyorum.

    CREATE TABLE string ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, string TEXT NOT NULL )

    CREATE TABLE word ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, word VARCHAR(14) NOT NULL UNIQUE, UNIQUE INDEX (word ASC) )

    CREATE TABLE word_string ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, string_id INT NOT NULL, word_id INT NOT NULL, word_order INT NOT NULL, FOREIGN KEY (string_id) REFERENCES (string.id), FOREIGN KEY (word_id) REFERENCES (word.id), INDEX (word_id ASC) )

    // Sample data INSERT INTO string (string) VALUES ('This is a test string'), ('The quick red fox jumped over the lazy brown dog')

    INSERT INTO word (word) VALUES ('this'), ('test'), ('string'), ('quick'), ('red'), ('fox'), ('jump'), ('over'), ('lazy'), ('brown'), ('dog')

    INSERT INTO word_string ( string_id, word_id, word_order ) VALUES ( 0, 0, 0 ), ( 0, 1, 3 ), ( 0, 2, 4 ), ( 1, 3, 1 ), ( 1, 4, 2 ), ( 1, 5, 3 ), ( 1, 6, 4 ), ( 1, 7, 5 ), ( 1, 8, 7 ), ( 1, 9, 8 ), ( 1, 10, 9 )

    // Sample query - find all strings containing 'fox' and 'quick' SELECT UNIQUE string.id, string.string FROM string INNER JOIN word_string ON string.id=word_string.string_id INNER JOIN word AS fox ON fox.word='fox' AND word_string.word_id=fox.id INNER JOIN word AS quick ON quick.word='quick' AND word_string.word_id=word.id

A iyi olduğunu doğru. O First Normal Form (her alan atomik olmalıdır) uymak için başarısız gibi B, aynı zamanda hiçbir iyidir. Eğer 1nF kaçınarak elde edeceğini göstermektedir sizin örnekte bir şey yok.

Sen kendi satırında her kelime ile kelime listenizi için bir masa istiyorum.