2012-12-04 8 views
6

Ich versuche ein Bestellsystem zu erstellen, aber ich stecke gerade fest. In der mysql-Tabelle verwende ich gerade varchar (255) in einer Spalte namens "bestillinger", aber es kann nur 255 Zeichen speichern. Also suchte ich ein bisschen, und daran erinnert, dass ich long oder einfach nur Text verwenden könnte, aber jetzt, wenn ich versuche, es zu tun, bekomme ich eine Fehlermeldung, dass:BLOB/TEXT-Spalte 'Bestilling' in der Schlüsselspezifikation ohne Schlüssellänge verwendet

#1170 - BLOB/TEXT column 'bestilling' used in key specification without a key length 

habe ich versucht, hier und in Google zu suchen, aber habe kein Glück mit mir.

Meine MySQL tabel ist:

CREATE TABLE IF NOT EXISTS `bestillinger` (
    `id` int(11) NOT NULL, 
    `bestilling` TEXT NOT NULL PRIMARY KEY, 
    `accepted` varchar(255) DEFAULT NULL, 
    UNIQUE KEY `id_bestilling` (`id`,`bestilling`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

I UNIQUE KEY verwenden, weil ich bin mit "ON DUPLICATE KEY UPDATE" in meinem PHP-Teil. Aber nichts dagegen.

Vielen Dank im Voraus.

+0

ist wirklich gute Erklärung, wie mit vorangestelltem Indizes beschäftigen: http://code-epicenter.com/prefixed-index-in-mysql-database/ – MrD

Antwort

7

Sie können einen Text nicht als Primärschlüssel festlegen. Mysql kann nur einige Zeichen indexieren und Text eingeben könnte zu groß sein, um zu indizieren.

werfen Sie einen Blick hier:

+0

Wie kann ich dann tun? Ich möchte lange Texte in einer Spalte speichern können? – Ismail

+0

erstellen Sie einen Textindex unter "Befüllen" und verwenden Sie eine andere Spalte als PK, wie etwas mit Autoinkrement. – jcho360

+0

Könnten Sie vielleicht ein Beispiel geben, bitte? Danke im Voraus. – Ismail

5

Von Ihrer Definition oben, und die ausführlichen Monolog in dieser Antwort unten ich die folgende Änderung vorschlagen:

CREATE TABLE IF NOT EXISTS `bestillinger` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `bestilling` TEXT NOT NULL, 
    `hashcode` CHAR(32) AS (MD5(bestilling)), 
    `accepted` VARCHAR(255) DEFAULT NULL, 
    UNIQUE KEY `id_bestilling` (hashcode,bestilling(333)) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

, die maximale Standardlänge für einen einspaltigen Indexschlüssel ist 1000 Bytes lang (767 bytes for InnoDB tables, es sei denn, Sie haben innodb_large_prefix gesetzt). Die gleiche Länge gilt für jedes Indexschlüssel-Präfix (die ersten N Zeichen für CHAR, VARCHAR, TEXT oder die ersten N Bytes für BINARY, VARBINARY, BLOB). Beachten Sie die Differenz zwischen Zeichen und Byte. Unter der Annahme eines UTF-8-Zeichensatzes und maximal 3 Bytes für jedes Zeichen könnten Sie dieses Limit mit einem Spaltenpräfixindex von mehr als 333 Zeichen in einer TEXT- oder VARCHAR-Spalte erreichen. In der Praxis ist 333 für mich ein guter Maximalwert.

Similarly in SQL Server, gibt es eine 900-Byte-Grenze für die maximale Gesamtgröße aller Indexschlüsselspalten.

Aber das verwendet nur die ersten Zeichen Ihres TEXT als Ihr Schlüssel, mit den offensichtlichen Kollisionen unmittelbar bevorstehend.

In der angenommenen Antwort ist der Vorschlag, eine FULLTEXT index zu verwenden. Ein FULLTEXT-Index ist speziell für die Textsuche entwickelt worden und hat eine nicht so gute Leistung für INSERT/DELETE, da er ein N-Gramm über dem Vokabular der Spaltenaufzeichnungen behält und den resultierenden Vektor speichert. Dies würde funktionieren, wenn jede Operation Textsuchfunktionen in einer Where-Klausel verwenden würde ... aber nicht für einen eindeutigen Index. Es gibt auch einen Primärschlüssel und einen eindeutigen Schlüssel, die auf "id" definiert sind, was redundant erscheint oder die Absicht verfehlt.

Stattdessen schlage ich einen berechneten Hash vor. Sie würden richtigerweise darauf hinweisen, dass es eine Chance gibt (Birthday Paradox), dass es eine Kollision mit einem Hash geben wird, also reicht ein UNIQUE Index allein nicht aus. Wir werden es mit einem Spaltenpräfix-Index verbinden, wie oben beschrieben, um uns an die Einzigartigkeit zu glauben.

entnehme ich die Absicht Ihrer ID-Spalte ist die richtigen Fremdschlüsselverweise aus anderen Tabellen zu ermöglichen. Ganz richtig, aber dann wäre das der nützlichere Primärschlüssel für diese Tabelle. Außerdem bezieht sich int (11) auf die Anzeigebreite der Spalte und nicht auf den zugrunde liegenden Wert. Ich habe auch ein 'unsigned auto_increment' auf 'id' gesetzt, um seine Rolle für das größere Publikum zu verdeutlichen.

Und das bringt uns zu dem vorgeschlagenen Entwurf oben.

+0

Ich habe einen solchen Fehler für den Typ Text. Die Länge wurde auf 100 festgelegt. Spaltenname war "E-Mail". Nach dem Ändern seines Typs in varchar ist der Fehler verschwunden. – CodeToLife

0

Verwendung dieses

CREATE TABLE IF NOT EXISTS `bestillinger` (
    `id` int(11) NOT NULL, 
    `bestilling` TEXT NOT NULL PRIMARY KEY, 
    `accepted` varchar(255) DEFAULT NULL, 
    UNIQUE KEY `id_bestilling` (`id`,`bestilling`(767)) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

ist die Grenze in mysql, während mit Blob/Textindizes Umgang

Ref: http://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html

0

Ich denke, das folgende Beispiel wird am besten dieses Problem erklären.

habe ich das Problem, weil ich ein Textfeld UNIQUE zu setzen versuchte. Ich habe das Problem behoben, indem ich den Datentyp der E-Mail (TEXT) in E-Mail geändert habe (VARCHAR (254)). Hier

mysql> desc users; 
+-------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-------------+-------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| fname  | varchar(50) | NO |  | NULL |    | 
| lname  | varchar(50) | NO |  | NULL |    | 
| uname  | varchar(20) | NO |  | NULL |    | 
| email  | text  | NO |  | NULL |    | 
| contact  | bigint(12) | NO |  | NULL |    | 
| profile_pic | text  | NO |  | NULL |    | 
| password | varchar(20) | NO |  | admin |    | 
+-------------+-------------+------+-----+---------+----------------+ 
8 rows in set (0.00 sec) 

mysql> ALTER TABLE users ADD UNIQUE(email); 
ERROR 1170 (42000): BLOB/TEXT column 'email' used in key specification without a key length 
mysql> 
mysql> ALTER TABLE users MODIFY email VARCHAR(254); 
Query OK, 9 rows affected (0.02 sec) 
Records: 9 Duplicates: 0 Warnings: 0 

mysql> ALTER TABLE users ADD UNIQUE(email); 
Query OK, 0 rows affected (0.02 sec) 
Records: 0 Duplicates: 0 Warnings: 0 

mysql> desc users; 
+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| fname  | varchar(50) | NO |  | NULL |    | 
| lname  | varchar(50) | NO |  | NULL |    | 
| uname  | varchar(20) | NO |  | NULL |    | 
| email  | varchar(254) | YES | UNI | NULL |    | 
| contact  | bigint(12) | NO |  | NULL |    | 
| profile_pic | text   | NO |  | NULL |    | 
| password | varchar(20) | NO |  | admin |    | 
+-------------+--------------+------+-----+---------+----------------+ 
8 rows in set (0.00 sec) 

mysql> 
Verwandte Themen