wake-up-neo.com

Warum kann eine Textspalte in MySQL keinen Standardwert haben?

Wenn Sie versuchen, eine TEXT-Spalte für eine Tabelle zu erstellen und in MySQL einen Standardwert festlegen, wird eine Fehlermeldung angezeigt (zumindest unter Windows). Ich kann keinen Grund erkennen, warum eine Textspalte keinen Standardwert haben sollte. Die MySQL-Dokumentation enthält keine Erklärung. Es scheint mir unlogisch (und etwas frustrierend, da ich einen Standardwert haben möchte!). Weiß jemand warum das nicht erlaubt ist?

159
Russ

Windows MySQL v5 gibt einen Fehler aus, aber Linux und andere Versionen geben nur eine Warnung aus. Dies muss behoben werden. WTF?

Sehen Sie auch einen Versuch, dies als Fehler # 19498 im MySQL Bugtracker zu beheben:

Bryce Nesbitt am 4. April 2008, 16:36 Uhr:
Unter MS Windows ist die Regel "no DEFAULT" ein Fehler, während es auf anderen Plattformen häufig eine Warnung ist. Dies ist zwar kein Fehler, aber es ist möglich, dass Sie davon betroffen sind, wenn Sie Code auf einer nachsichtigen Plattform schreiben und ihn später auf einer strengen Plattform ausführen:

Persönlich sehe ich das als einen Bug. Die Suche nach "BLOB/TEXT-Spalte kann keinen Standardwert haben" liefert bei Google ungefähr 2.940 Ergebnisse. Bei den meisten handelt es sich um Berichte über Inkompatibilitäten bei der Installation von DB-Skripten, die auf einem System funktionierten, auf anderen jedoch nicht.

Auf einer Webanwendung, die ich für einen meiner Clients ändere und die ursprünglich unter Linux MySQL v5.0.83-log bereitgestellt wurde, tritt das gleiche Problem auf. Ich verwende Windows MySQL v5.1.41. Selbst wenn Sie versuchen, die neueste Version von phpMyAdmin zum Extrahieren der Datenbank zu verwenden, wird für die betreffende Textspalte kein Standard gemeldet. Wenn ich jedoch versuche, eine Einfügung unter Windows auszuführen (dies funktioniert in der Linux-Bereitstellung einwandfrei), wird in der ABC-Spalte ein Fehler ohne Standard angezeigt. Ich versuche, die Tabelle lokal mit dem offensichtlichen Standard (basierend auf einer Auswahl eindeutiger Werte für diese Spalte) neu zu erstellen und erhalte am Ende die ach so nützliche BLOB/TEXT-Spalte kann keinen Standardwert haben.

Auch hier ist die Nichteinhaltung der grundlegenden Kompatibilität zwischen Plattformen inakzeptabel und ein Fehler.


So deaktivieren Sie den strikten Modus in MySQL 5 (Windows):

  • Bearbeite /my.ini und suche die Zeile

    sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
    
  • Ersetzen Sie es durch

    sql_mode='MYSQL40'
    
  • Starten Sie den MySQL-Dienst neu (vorausgesetzt, es handelt sich um mysql5)

    net stop mysql5
    net start mysql5
    

Wenn Sie root/admin-Zugriff haben, können Sie möglicherweise ausführen

mysql_query("SET @@global.sql_mode='MYSQL40'");
82
Ku Logix

Ohne tiefes Wissen über die mySQL-Engine würde ich sagen, dass dies wie eine Strategie zum Speichern von Speicher klingt. Ich gehe davon aus, dass der Grund für diesen Absatz in docs liegt:

Jeder BLOB- oder TEXT-Wert wird intern durch ein separat zugewiesenes Objekt dargestellt. Dies steht im Gegensatz zu allen anderen Datentypen, für die beim Öffnen der Tabelle einmal pro Spalte Speicher zugewiesen wird.

Es scheint, als würde das Vorfüllen dieser Spaltentypen zu Speicherauslastung und Leistungseinbußen führen.

26
Pekka 웃

Mit einem Trigger können Sie den gleichen Effekt wie mit einem Standardwert erzielen

create table my_text

(
   abc text
);

delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
   if (NEW.abc is null ) then
      set NEW.abc = 'default text';
   end if;
end
//
delimiter ;
14
Tim Child

"Unterstützung für DEFAULT in TEXT/BLOB-Spalten" ist ein Funktionsanforderung im MySQL Bugtracker (Bug # 21532) .

Ich sehe, dass ich nicht der einzige bin, der einen Standardwert in eine TEXT-Spalte einfügen möchte. Ich denke, diese Funktion sollte in einer späteren Version von MySQL unterstützt werden.

Dies kann in der Version 5.0 von MySQL nicht behoben werden, da dies anscheinend zu Inkompatibilität und Datenverlust führen würde, wenn jemand versucht, eine Datenbank zwischen den (aktuellen) Datenbanken, die diese Funktion nicht unterstützen, und Datenbanken, die diese Funktion unterstützen, hin und her zu übertragen diese Funktion.

9
David Cary

Als Hauptfrage:

Weiß jemand warum das nicht erlaubt ist?

wird immer noch nicht beantwortet, ich habe eine Schnellsuche durchgeführt und eine relativ neue Ergänzung von einem MySQL-Entwickler bei MySQL Bugs gefunden:

[17 Mar 2017 15:11] Ståle Deraas

Gepostet vom Entwickler:

Dies ist in der Tat eine gültige Feature-Anfrage, und auf den ersten Blick scheint es trivial, sie hinzuzufügen. TEXT/BLOBS-Werte werden jedoch nicht direkt im Datensatzpuffer gespeichert, der zum Lesen/Aktualisieren von Tabellen verwendet wird. Das Zuweisen von Standardwerten ist daher etwas komplexer.

Dies ist keine definitive Antwort, aber zumindest ein Ausgangspunkt für die Warum Frage.

In der Zwischenzeit werde ich es einfach umgehen und entweder die Spalte nullfähig machen oder explizit ein (default '') Wert für jeden insert aus dem Anwendungscode ...

6
Marten Koetsier

Normalerweise führe ich Websites unter Linux aus, aber ich entwickle auch auf einem lokalen Windows-Computer. Ich bin oft auf dieses Problem gestoßen und habe gerade die Tabellen repariert, als ich auf die Probleme gestoßen bin. Ich habe gestern eine App installiert, um jemandem zu helfen, und bin natürlich wieder auf das Problem gestoßen. Also entschied ich, dass es Zeit war herauszufinden, was los war - und fand diesen Thread. Die Idee, den sql_mode des Servers in einen früheren Modus zu versetzen (standardmäßig), gefällt mir wirklich nicht, deshalb habe ich eine einfache (meiner Meinung nach) Lösung gefunden.

Diese Lösung würde natürlich erfordern, dass Entwickler ihre Tabellenerstellungsskripte umbrechen, um das unter Windows ausgeführte MySQL-Problem zu kompensieren. In Dump-Dateien werden ähnliche Konzepte angezeigt. Eine große Einschränkung ist, dass dies Probleme verursachen kann/wird, wenn die Partitionierung verwendet wird.

// Store the current sql_mode
mysql_query("set @orig_mode = @@global.sql_mode");

// Set sql_mode to one that won't trigger errors...
mysql_query('set @@global.sql_mode = "MYSQL40"');

/**
 * Do table creations here...
 */

// Change it back to original sql_mode
mysql_query('set @@global.sql_mode = @orig_mode');

Das ist alles.

6

Für Ubuntu 16.04:

So deaktivieren Sie den strikten Modus in MySQL 5.7:

Bearbeiten Sie die Datei /etc/mysql/mysql.conf.d/mysqld.cnf

Wenn die folgende Zeile in mysql.cnf vorhanden ist

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Ersetzen Sie es dann durch

sql_mode='MYSQL40'

Andernfalls

Fügen Sie einfach die folgende Zeile in mysqld.cnf hinzu

sql_mode='MYSQL40'

Das Problem wurde behoben.

1
ShivBuyya