2010-12-14 7 views
1

Hier ist meine Warentabelle.MYSQL - wie zu einem zweiten eindeutigen String-Schlüssel?

+----------------------+---------------+------+-----+---------+-------+ 
| Field    | Type   | Null | Key | Default | Extra | 
+----------------------+---------------+------+-----+---------+-------+ 
| ID     | decimal(18,0) | NO | PRI |   |  | 
| gkey     | varchar(255) | YES | MUL | NULL |  | 
| GOODS    | decimal(18,0) | YES | MUL | NULL |  | 

Spalten-ID ist Auto-Inkrement. WAREN ist die ID einer Warenkategorie. Hier ist die Warenartentabelle.

+-------+---------------------+ 
| ID | NAME    | 
+-------+---------------------+ 
| 1  | book    | 
| 2  | phone    | 
+-------+---------------------+ 

Meine Frage ist in Waren Tabelle muß ich die gTaste ist auch ein eindeutiger Schlüssel mit dem Präfix-ID Wie BOOK-1, BOOK-2 .... PHONE-1 (hier ID von 1 gestartet wird) , PHONE-2 ... beim Einfügen eines neuen Warensatzes in die Warenliste. wie folgt aus:

+--------------------+---------------+------+-----+---------+-------+ 
| ID     | GKEY   |GOODS | PRI | COUNTRY | Extra | 
+--------------------+---------------+------+-----+---------+-------+ 
| 1     | BOOK-1  | 1 | 10 |   |  | 
| 2     | PHONE-1  | 2 | 12 |   |  | 
| 3     | BOOK-2  | 1 | 13 |   |  | 
| 4     | BOOK-3  | 1 | 10 |   |  | 
| 5     | PHONE-2  | 2 | 10 |   |  | 
| 6     | PHONE-3  | 2 | 20 |   |  | 
+--------------------+---------------+------+-----+---------+-------+ 

Wie diese GTaste in PHP und MySQL zu bekommen?

danke.

+1

Gibt es einen bestimmten Grund für diesen Ansatz? –

+0

Meine wirklich erste Frage wäre ... warum 'dezimal', aber warum? – Danosaure

Antwort

0

Sie können die UNIQUE-Einschränkung verwenden. Weitere Informationen finden Sie unter here.

+0

Das Hinzufügen einer UNIQUE-Einschränkung ist wichtig, um das versehentliche Duplizieren von Schlüsseln zu verhindern. Aber die Einschränkung hilft Ihnen nicht, die Schlüssel an erster Stelle zu erzeugen, also benötigen Sie mehr als das. –

0

Ich glaube nicht, dass Sie das überhaupt tun wollen. Stattdessen sollte good.gkey ein Fremdschlüssel zu goods_category.id sein. Wenn der Anzeigenauftrag wichtig ist, können Sie ein insert_date Datumsfeld zur Warentabelle hinzufügen.

Von dort können Sie alle Arten von Abfragen ausführen, mit dem zusätzlichen Vorteil referenzieller Integrität auf Ihren Tischen.

+0

Keine Gründe. Das ist die Anforderung von meinem Chef. Ich muss es nur ausführen. ps: Boss sagte, dass dieses Design Jira ähnlich ist – acai

+0

Es gibt bereits einen Fremdschlüssel von 'goods.goods' zu' good_categories.id' – Danosaure

0

Zuerst sollten Sie alles Datenbankseite tun. Also kein PHP. Das wäre mein Rat.

mit dann nicht Sequenz in MySQL das, was ich würde Ihnen vorschlagen:

SELECT COUNT(id) 
FROM GOODS 
WHERE GKEY LIKE('BOOK-%') 

Sie dann Sie die nächste Nummer verfügbar wird immer

INSERT INTO goods (id, "BOOK-" || SELECT MAX(SUBSTR(LENGTH(GKEY -1), LENGTH(GKEY))FROM GOODS WHERE GKEY LIKE('BOOK-%') + 1, ...) 

Auf diese Weise einfügen.

+0

Das ist keine gute Lösung. Wenn er einen Datensatz löscht, entspricht 'COUNT (id)' nicht mehr der zuletzt eingefügten Zahl. Ich denke, er muss seine Datenbank besser normalisieren, dann wird alles andere einfacher. – AgentConundrum

+0

Und ich stimme zu. Aber vielleicht hat er einen Kundenauftrag, der aus irgendeinem Grund so will. Das Design ist schrecklich, aber es gibt keine Sequenzen in MySQL, um seine Bedürfnisse zu erfüllen, die die Antwort auf die Schlussfolgerung ist, mit der ich kommen kann. Stimmst du nicht zu? – Spredzy

+0

Datenbank normalisieren? Könntest du mir die Details geben? Ich habe keine Ahnung davon. – acai

0

Sie können es tun, aber Sie müssen sehr vorsichtig sein, um sicherzustellen, dass zwei gleichzeitige Einsätze nicht den gleichen Schlüssel erhalten. Ich würde entwerfen es mit diesen beiden Konstruktionspunkte:

  1. In der GoodsCategory Tabelle, haben einen Zähler, die den nächsten gTaste zu erzeugen hilft.
  2. Verwenden Sie Sperren, so dass nur ein Prozess einen neuen Schlüssel zu jeder Zeit generieren kann.

Hier die Details:
1. ein paar Spalten zur GoodsCategory Tabelle hinzufügen:

+----------------------+---------------+------+-----+---------+-------+ 
| Field    | Type   | Null | Key | Default | Extra | 
+----------------------+---------------+------+-----+---------+-------+ 
| ID     | TINYINT  | NO | PRI |   |  | 
| NAME     | VARCHAR(80) | NO |  |   |  | 
| KeyCode    | CHAR(5)  | NO |  |   |  | 
| NextID    | INT   | NO |  | 0  |  | 
+----------------------+---------------+------+-----+---------+-------+ 

Die KeyCode hat 'Buch' oder 'PHONE' und die NextID Feld speichert ein int die verwendet wird, um die nächsten Schlüssel dieses Typ, dh zu erzeugen, wenn die Tabelle wie folgt aussieht:

+----------------+------------+---------+--------+ 
| ID    | NAME  | KeyCode | NextID | 
+----------------+------------+---------+--------+ 
| 1    | book  | BOOK | 3  | 
| 2    | phone  | PHONE | 7  | 
+----------------+------------+---------+--------+ 

Dann wird das nächste Mal, wenn Sie ein Buch hinzufügen, sollte es gegeben gTaste ‚bOOK-3‘ werden und NextID erhöhen auf 4.

2: Die Sperren müssen in einer gespeicherten Routine getan werden, da sie mehrere Anweisungen in einer Transaktion beinhaltet und verwendet auch lokale Variablen. Der Kern sollte es in etwa so aussehen:

START TRANSACTION; 
SELECT KeyCode, NextID INTO v_kc, v_int FROM GoodsCategory WHERE ID = 2 FOR UPDATE; 
SET v_newgkey = v_kc + '-' + CAST(v_int AS CHAR); 
INSERT INTO goods (gkey, goods, ...) VALUES (v_newgkey, 2, etc); 
UPDATE GoodsCategory SET NextID = NextID + 1 WHERE ID = 2; 
COMMIT; 

Die FOR UPDATE Bit ist von entscheidender Bedeutung; Werfen Sie einen Blick auf die Verwendungsbeispiele in der mysql manual, wo erläutert, wie Sperren verwenden, um eine ID ohne Beeinträchtigung durch einen anderen Prozess zu generieren.