Unterschiedliches Verhalten von CREATE TABLE

Unterschiedliches Verhalten von CREATE TABLE

am 31.05.2007 12:29:42 von Torsten Robitzki

Hallo,
ich bin hier gerade über eine Sache gestolpert, bei der ich einen Rat=20
gebrauchen könnte. Ich habe eine Ruby on Rails Applikation, bei der ich=
=20
das Datenbankschema mit einem SQL-Skript, mit jeder Menge CREATE TABLE=20
erzeuge. Auf zwei Rechnern verhalten sich diese Statments nun=20
unterschiedlich. Folgendes Beispiel:

CREATE TABLE test (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
company_type INTEGER UNSIGNED NOT NULL,
PRIMARY KEY(id)
)
TYPE=3DInnoDB;

Erzeugt einmal mit Version 5.0.18:
mysql> desc test;
+--------------+------------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+--------------+------------------+------+-----+---------+
| id | int(10) unsigned | NO | PRI | NULL |
| company_type | int(10) unsigned | NO | | |=20
+--------------+------------------+------+-----+---------+
2 rows in set (0.00 sec)

und ein anderes mal mit Version 5.0.21:
mysql> desc test
-> ;
+--------------+------------------+------+-----+---------+
| Field | Type | Null | Key | Default |=20
+--------------+------------------+------+-----+---------+
| id | int(10) unsigned | NO | PRI | NULL |
| company_type | int(10) unsigned | NO | | NULL |
+--------------+------------------+------+-----+---------+
2 rows in set (0.02 sec)

Der Unterschied ist das Default für die zweite Spalte. Meine Applikatio=
n=20
füllt dieses Feld in manchen Fällen nicht und es wird von der Datenba=
nk=20
im 2. Fall auf 0 gesetzt. Jetzt frage ich mich, ob der Unterschied in=20
der Datenbankversion liegt, oder ob der Unterschied in der Konfiguration =

liegt.

mfg Torsten

Re: Unterschiedliches Verhalten von CREATE TABLE

am 31.05.2007 12:45:14 von Dietmar Staritz

> Der Unterschied ist das Default für die zweite Spalte. Meine Applikation
> füllt dieses Feld in manchen Fällen nicht und es wird von der Datenbank
> im 2. Fall auf 0 gesetzt. Jetzt frage ich mich, ob der Unterschied in
> der Datenbankversion liegt, oder ob der Unterschied in der Konfiguration
> liegt.
>
> mfg Torsten

Ich kann zwar nix zu den Innereien der beiden Versionen sagen, nur die
Aussag ist für mich ein und die selbe, Wenn ich nix angebe, dann ist,
egal ob ich dazu default-Wert sage oder nicht der Wert/Inhalt der Spalte
NULL (=LEER) - nicht zu verwechseln mit dem Zahlenwert 0
Wenn das nur der einzige Punkt ist, der dich dabei stört, kannst du
ruhig weitermachen, weil wenn deine Applikation nen Wert mit rübergibt,
wird der Defaultwert überschrieben , als Leer wird mit dem übergeben
Wert gefüllt.

Dietmar

Re: Unterschiedliches Verhalten von CREATE TABLE

am 31.05.2007 13:16:29 von Torsten Robitzki

Hallo Dietmar,

> Ich kann zwar nix zu den Innereien der beiden Versionen sagen, nur die =

> Aussag ist für mich ein und die selbe, Wenn ich nix angebe, dann ist,=
=20
> egal ob ich dazu default-Wert sage oder nicht der Wert/Inhalt der Spalt=
e=20
> NULL (=3DLEER) - nicht zu verwechseln mit dem Zahlenwert 0
> Wenn das nur der einzige Punkt ist, der dich dabei stört, kannst du=20
> ruhig weitermachen, weil wenn deine Applikation nen Wert mit rübergib=
t,=20
> wird der Defaultwert überschrieben , als Leer wird mit dem übergebe=
n=20
> Wert gefüllt.

ja stimmt. Aber ups, bei der ersten Version, kann ich mit
insert into test values ();
einen record in der DB anlegen. Bei der zweiten version (das ist die, wo =

das default als NULL gesetzt ist, geht es nicht. Also schon mal genau=20
anders herum, als ich es vermutet hätte. Rails hat aber ein Problem mit=
=20
der ersten Variante. Ich vermute mal, das sich Rails beim Start der=20
Applikation eine Beschreibung der Tabelle von der Datenbank besorgt und=20
daher unterschiedlich reagiert. Im gg. Fall erzeugt Rails ein
insert into test value(NULL), wahrscheinlich weil die Zeile kein default =

hat, da die Zeile aber not null ist, funktioniert das natürlich auch ni=
cht.

mfg Torsten

Re: Unterschiedliches Verhalten von CREATE TABLE

am 31.05.2007 13:31:53 von Dietmar Staritz

> ja stimmt. Aber ups, bei der ersten Version, kann ich mit
> insert into test values ();
> einen record in der DB anlegen. Bei der zweiten version (das ist die, wo
> das default als NULL gesetzt ist, geht es nicht. Also schon mal genau
> anders herum, als ich es vermutet hätte. Rails hat aber ein Problem mit
> der ersten Variante. Ich vermute mal, das sich Rails beim Start der
> Applikation eine Beschreibung der Tabelle von der Datenbank besorgt und
> daher unterschiedlich reagiert. Im gg. Fall erzeugt Rails ein
> insert into test value(NULL), wahrscheinlich weil die Zeile kein default
> hat, da die Zeile aber not null ist, funktioniert das natürlich auch nicht.
>
> mfg Torsten
>
Nach meinem Verständnis dürfte in beiden !!! sich keine Zeile anlegen
lassen. Das er default als NULL bezeichnet, würde mich nicht stören,
vermutlich zeigt er damit nur an, das nichts definiert ist als
"defaultwert". Vielmehr gibt mir zu denken, das trotz NOT NULL auf
company_type sich eine Zeile einfügen lässt. Das halte ich schlichtweg
für einen Bug, der whr. behoben wurde in der neueren Version.

Dietmar

Re: Unterschiedliches Verhalten von CREATE TABLE

am 31.05.2007 15:42:41 von Torsten Robitzki

So, jetzt habe ich mySQL 5.0.41 installiert, dadurch wird es erstmal=20
nicht besser, sondern nun führen Kommentare im Create-Script dazu, das =

alle TABLE CREATE Anweisungen hinter einem Kommentar ohne Fehlermeldung=20
nicht mehr ausgeführt werden. Hat ein Kommentar wie:

-- ------------------------------------------------------------
-- Beschreibt, wie viele EPs es fr den Bau eines Geb...
-- ------------------------------------------------------------

syntaktisch eine besondere Bedeutung oder bin ich schon wieder über den=
=20
nächsten Bug gestolpert? Was für ein Sch...

mfg Torsten

Re: Unterschiedliches Verhalten von CREATE TABLE

am 31.05.2007 16:10:37 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 00:57:16 von Axel Schwenke

Torsten Robitzki wrote:

> CREATE TABLE test (
> id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
> company_type INTEGER UNSIGNED NOT NULL,
> PRIMARY KEY(id)
> )
> TYPE=InnoDB;
>
> Erzeugt einmal mit Version 5.0.18:
>+--------------+------------------+------+-----+---------+
>| Field | Type | Null | Key | Default |
>+--------------+------------------+------+-----+---------+
>| id | int(10) unsigned | NO | PRI | NULL |
>| company_type | int(10) unsigned | NO | | |
>+--------------+------------------+------+-----+---------+
>
> und ein anderes mal mit Version 5.0.21:
>+--------------+------------------+------+-----+---------+
>| Field | Type | Null | Key | Default |
>+--------------+------------------+------+-----+---------+
>| id | int(10) unsigned | NO | PRI | NULL |
>| company_type | int(10) unsigned | NO | | NULL |
>+--------------+------------------+------+-----+---------+

Das ist Jacke wie Hose. Wenn du im CREATE TABLE für eine Spalte NOT
NULL aber kein DEFAULT stehen hast, dann kann MySQL in der DEFAULT-
Spalte wahlweise nix oder NULL stehen haben. Beides bedeutet "der User
hat nix angegeben" und IMHO ist letztere Variante etwas konformer mit
SQL, wo genau dafür typischerweise NULL steht.

AUTO_INCREMENT ist ein anderes Kapitel. Da *kann* es als Defaultwert
nur NULL geben. Und NULL bedeutet "erzeuge eine neue id".


Eine weitere Besonderheit von MySQL ist, daß es in der Standard-
Konfiguration erlaubt, NOT NULL Spalten auf NULL zu setzen. Etwa durch

INSERT INTO test VALUES ()

hier wird eine neue id bestimmt und company_type auf den Defaultwert
für den Spaltentyp (bei INT: 0) gesetzt. MySQL-Versionen ab 5.0 kennen
SQL-Modes:
http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html

mit SQL_MODE='TRADITIONAL' verzeiht MySQL das dann nicht mehr:

mysql> CREATE TABLE test (
-> id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-> company_type INTEGER UNSIGNED NOT NULL,
-> PRIMARY KEY(id)
-> )
-> TYPE=InnoDB;
Query OK, 0 rows affected, 2 warnings (0,01 sec)

mysql> insert into test values ();
Query OK, 1 row affected, 1 warning (0,00 sec)

mysql> show warnings;
+---------+------+------------------------------------------ ---------+
| Level | Code | Message |
+---------+------+------------------------------------------ ---------+
| Warning | 1364 | Field 'company_type' doesn't have a default value |
+---------+------+------------------------------------------ ---------+
1 row in set (0,00 sec)

mysql> select * from test;
+----+--------------+
| id | company_type |
+----+--------------+
| 1 | 0 |
+----+--------------+
1 row in set (0,00 sec)

mysql> set sql_mode='TRADITIONAL';
Query OK, 0 rows affected (0,00 sec)

mysql> insert into test values ();
ERROR 1364 (HY000): Field 'company_type' doesn't have a default value



XL

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 01:00:25 von Axel Schwenke

Torsten Robitzki wrote:
> So, jetzt habe ich mySQL 5.0.41 installiert, dadurch wird es erstmal
> nicht besser, sondern nun führen Kommentare im Create-Script dazu, das
> alle TABLE CREATE Anweisungen hinter einem Kommentar ohne Fehlermeldung
> nicht mehr ausgeführt werden.

Diesen Satz verstehe ich nicht.

> Hat ein Kommentar wie:
>
> -- ------------------------------------------------------------
> -- Beschreibt, wie viele EPs es fr den Bau eines Geb...
> -- ------------------------------------------------------------
>
> syntaktisch eine besondere Bedeutung oder bin ich schon wieder über den
> nächsten Bug gestolpert?

Womöglich sind ja deine Zeilenenden kaputt. Oder die Umlaute
entsprechen nicht der Deklaration und bringen so den Parser
im Kommandozeilenclient durcheinander.


XL

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 07:28:58 von Torsten Robitzki

Axel Schwenke wrote:

> MySQL-Versionen ab 5.0 kennen
> SQL-Modes:
> http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html
>
> mit SQL_MODE='TRADITIONAL' verzeiht MySQL das dann nicht mehr:

Dank Dir Axel,

mfg Torsten

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 07:36:17 von Torsten Robitzki

Andreas Kretschmer wrote:

> begin Torsten Robitzki schrieb:
>=20
>>So, jetzt habe ich mySQL 5.0.41 installiert, dadurch wird es erstmal=20
>>nicht besser, sondern nun führen Kommentare im Create-Script dazu, da=
s=20
>>alle TABLE CREATE Anweisungen hinter einem Kommentar ohne Fehlermeldung=
=20
>>nicht mehr ausgeführt werden. Hat ein Kommentar wie:
>>
>>-- ------------------------------------------------------------
>>-- Beschreibt, wie viele EPs es fr den Bau eines Geb...
>>-- ------------------------------------------------------------
>=20
> ^
> Zeichensatz-Problem?

Guter Hinweis, aber jetzt tritt das Problem nicht mehr auf.

mfg Torsten

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 13:11:32 von Andreas Scherbaum

Axel Schwenke wrote:
>
> Eine weitere Besonderheit von MySQL ist, daß es in der Standard-
> Konfiguration erlaubt, NOT NULL Spalten auf NULL zu setzen.

Habe ich diesen Satz eben richtig gelesen und interpretiert?
Welchen Sinn hat so ein Verhalten?


Bye

--
Andreas 'ads' Scherbaum
Failure is not an option. It comes bundled with your Microsoft product.
(Ferenc Mantfeld)

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 15:11:54 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 16:36:14 von Axel Schwenke

Andreas Scherbaum wrote:
> Axel Schwenke wrote:
>>
>> Eine weitere Besonderheit von MySQL ist, daß es in der Standard-
>> Konfiguration erlaubt, NOT NULL Spalten auf NULL zu setzen.
>
> Habe ich diesen Satz eben richtig gelesen und interpretiert?

Der Satz hätte vielleicht noch weiter gehen sollen mit: "und in diesem
Fall NULL durch einen kanonischen Default-Wert (der vom Typ der Spalte
abhängt) ersetzt."

> Welchen Sinn hat so ein Verhalten?

Das Verhalten stammt aus der Zeit, als MySQL noch kein transaktions-
fähiges Backend hatte. Ein multi-Value INSERT a'la

INSERT INTO test (company_type) VALUES (1), (NULL), (42)

würde man normalerweise als Ganzes zurückweisen. Wenn die Engine aber
keine Transaktionen kann, müßte man beim zweiten Datensatz abbrechen
und hätte so ein teilweise ausgeführtes Statement. Damals wurde
wohl entschieden, daß es dann besser ist, NULL durch einen Defaultwert
zu ersetzen und das Statement komplett auszuführen.

Heute ist es aus Gründen der Kompatibilität noch das Default-Verhalten.
Wer diese Kompatibilität nicht braucht (und das richtige Backend für
seine Tabellen verwendet) kann es ja umstellen.


XL

Re: Unterschiedliches Verhalten von CREATE TABLE

am 01.06.2007 18:50:16 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)