MySQL, besser NULL oder leere Zeichenfolge einfügen?

230

Ich habe ein Formular auf einer Website, die viele verschiedene Bereiche hat. Einige der Felder sind optional, während andere obligatorisch sind. In meiner Datenbank habe ich eine Tabelle, die alle diese Werte enthält. Ist es besser, einen NULL-Wert oder eine leere Zeichenfolge in die DB-Spalten einzufügen, in die der Benutzer keine Daten eingegeben hat?

Roflwaffel
quelle

Antworten:

220

Mit können NULLSie zwischen "Keine Daten einfügen" und "Leere Daten einfügen" unterscheiden.

Einige weitere Unterschiede:

  • A LENGTHvon NULList NULL, a LENGTHvon einer leeren Zeichenfolge ist 0.

  • NULLs werden vor den leeren Zeichenfolgen sortiert.

  • COUNT(message)zählt leere Strings, aber nicht NULLs

  • Sie können mit einer gebundenen Variablen nach einer leeren Zeichenfolge suchen, nicht jedoch mit einer NULL. Diese Abfrage:

    SELECT  *
    FROM    mytable 
    WHERE   mytext = ?

    wird niemals mit einem NULLin übereinstimmen mytext, egal welchen Wert Sie vom Client übergeben. Um mit NULLs übereinzustimmen, müssen Sie eine andere Abfrage verwenden:

    SELECT  *
    FROM    mytable 
    WHERE   mytext IS NULL
Quassnoi
quelle
3
aber welches denkst du ist schneller? 0 oder NULL oder ""
Atul Dravid
8
in InnoDB NULL nehmen weniger Platz ein
Timo Huovinen
37
Ich denke, dies ist eine gute Antwort, aber sie ignoriert auch das "Best Practice" -Element der Frage völlig und konzentriert sich nur auf tangential relevante Fakten (NULL-Sortierreihenfolge und -länge? Diese spielen keine Rolle). Bei den meisten Eingabetypen für Textdaten gibt es keinen Unterschied zwischen "keine Antwort" und "leere Antwort". Ich denke, dies ist eine großartige Frage, die eine bessere Antwort verdient.
Nick
6
NULL-Werte funktionieren auch hervorragend, wenn das Feld UNIQUE festgelegt ist. Zum Beispiel, wenn Sie ein Feld wie Führerschein haben, um die DL-Nummer einer Person hinzuzufügen, und der Typ sie nicht hat. Da es sich um ein eindeutiges Feld handelt, wird die erste Person ohne DL-Nummer hinzugefügt, nicht jedoch die nächste, da dies einen Fehler mit eindeutiger Einschränkung auslöst. NULL ist also besser.
Saifur Rahman Mohsin
1
@Quassnoi ah sorry ... ich meinte, warum ist es eine schlechte Praxis, den Führerschein als eindeutig festzulegen ...?
Cedbeu
44

Wenn Sie jemals vorhaben, die Datenbank zu wechseln , sollten Sie berücksichtigen, dass Oracle keine leeren Zeichenfolgen unterstützt . Sie werden automatisch in NULL konvertiert und können nicht mit Klauseln wie abgefragt werden WHERE somefield = ''.

Matt Solnit
quelle
11
Das klang für mich unglaublich faul, selbst auf Ihrem Link, also habe ich es versucht. Nullfeld, auf '' gesetzt, Orakel ignoriert es. Meldet die Länge als null anstatt als 0. Das ist einfach so falsch. Daran muss es einen Weg geben. Ich denke, ich werde dies als eine weitere Frage posten.
Steve B.
1
Steve B.: siehe diese Frage: stackoverflow.com/questions/1171196/…
Quassnoi
Vielen Dank für den Hinweis, obwohl ich die Argumentation immer noch nicht verstehe. Gepostet
Steve B.
Es könnte sich lohnen, die Antwort zu aktualisieren, um Informationen über den von Quassnoi geposteten Link aufzunehmen
SamuelKDavis am
7
Peoplesoft (mit Oracle DB) verwendet ein einzelnes Leerzeichen, um einen leeren Wert anzugeben. Unglaublich dumm. Sie verwenden auch 0,00025, um 0 für FTE anzugeben, da 0 nicht zulässig ist. In diesem Produkt wurden schöne Entscheidungen getroffen.
JP Duffy
9

Beachten Sie, dass NULL Ihre Codepfade möglicherweise erheblich erschwert. In Python zum Beispiel die meisten Datenbank - Adapter / ORMs Karte NULLzu None.

Also Dinge wie:

print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow

könnte zu "Hallo, keine Joe Doe!" Um dies zu vermeiden, benötigen Sie so etwas wie diesen Code:

if databaserow.title:
    print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
else:
    print "Hello, %(firstname) %(lastname)!" % databaserow

Das kann die Dinge viel komplexer machen.

max
quelle
25
Meiner Meinung nach ist der Missbrauch Ihrer Datenbank zur "Behebung" von Fehlern in Ihrem Code oder im Framework eine (sehr) schlechte Codierungspraxis. Wenn keine Daten vorhanden sind, sollten Sie einfach NULL einfügen und diese konsistent verwenden. Andernfalls müssen Sie folgende Anweisungen verwenden: if (myString == null || myString = ""). Wenn ein Objekt in Ihrem Code nicht festgelegt oder definiert ist, verwenden Sie auch NULL anstelle einer Art "Platzhalter" (was meiner Meinung nach eine leere Zeichenfolge ist).
Gertjan
5
Hängt sehr von der Sprache Ihrer Wahl ab. In Python "wenn nicht myString:" testet auf None und "". Wahrscheinlich hauptsächlich ein kulturelles Problem. Die "schlechte Praxis" der Java Guys ist die Eleganz der dynamischen Person.
Max
9

Besser einfügen, NULLum die Konsistenz in Ihrer Datenbank in MySQL zu gewährleisten. Fremdschlüssel können als gespeichert werdenNULL aber NICHT als leere Zeichenfolgen .

Sie haben Probleme mit einer leeren Zeichenfolge in den Einschränkungen. Möglicherweise müssen Sie einen gefälschten Datensatz mit einer eindeutigen leeren Zeichenfolge einfügen , um eine Fremdschlüsseleinschränkung zu erfüllen. Schlechte Praxis, denke ich.

Siehe auch: Kann ein Fremdschlüssel NULL und / oder doppelt sein?

Micaball
quelle
Das Problem mit den Einschränkungen hat mich in der Vergangenheit gestolpert, deshalb habe ich diese Antwort "+1".
HPWD
Wenn Sie jedoch NULL verwenden, stellen Sie sicher, dass Sie auch keine leeren Zeichenfolgen erhalten. Einfach mit vielen UI-Technologien zu tun.
Tuntable
5

Ich weiß nicht, was hier die beste Vorgehensweise wäre, aber ich würde mich im Allgemeinen für die Null irren, es sei denn, Sie möchten, dass Null etwas anderes als eine leere Zeichenfolge bedeutet und die Benutzereingabe mit Ihrer Definition einer leeren Zeichenfolge übereinstimmt.

Beachten Sie, dass ich sage, dass SIE definieren müssen, wie sie unterschiedlich sein sollen. Manchmal ist es sinnvoll, sie anders zu haben, manchmal nicht. Wenn nicht, wählen Sie einfach eine aus und bleiben Sie dabei. Wie gesagt, ich tendiere dazu, die NULL die meiste Zeit zu bevorzugen.

Oh, und denken Sie daran, dass, wenn die Spalte null ist, der Datensatz weniger wahrscheinlich in praktisch jeder Abfrage erscheint, die basierend auf dieser Spalte eine where-Klausel (in SQL-Begriffen) auswählt (es sei denn, die Auswahl bezieht sich auf eine Nullspalte) natürlich.

Platinum Azure
quelle
1
... Und jetzt, wo ich die Antwort über mir sehe, kann ich mit Sicherheit sagen, dass die übliche Unterscheidung, die Sie interessieren würden, keine Daten gegenüber leeren Daten ist. :-)
Platinum Azure
1

Wenn Sie mehrere Spalten in einem eindeutigen Index verwenden und mindestens eine dieser Spalten obligatorisch ist (dh ein erforderliches Formularfeld), können Sie doppelte Zeilen erhalten, wenn Sie die anderen Spalten im Index auf NULL setzen. Dies liegt daran, dass NULL-Werte in eindeutigen Spalten ignoriert werden. Verwenden Sie in diesem Fall leere Zeichenfolgen in den anderen Spalten des eindeutigen Index, um doppelte Zeilen zu vermeiden.

SPALTEN IN EINEM EINZIGARTIGEN INDEX:
(event_type_id, event_title, Datum, Ort, URL)

BEISPIEL 1:
(1, 'BBQ', '2018-07-27', null, null)
(1, 'BBQ', '2018-07-27', null, null) // erlaubt und dupliziert.

BEISPIEL 2:
(1, 'BBQ', '2018-07-27', '', '')
(1, 'BBQ', '2018-07-27', '', '') // NICHT erlaubt, da es dupliziert wird.

Hier sind einige Codes:

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `event_id` int(11) DEFAULT NULL,
  `event_title` varchar(50) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  `url` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `event_id` (`event_id`,`event_title`,`date`,`location`,`url`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Fügen Sie dies nun ein, um zu sehen, dass die duplizierten Zeilen zulässig sind:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

Fügen Sie nun dies ein und überprüfen Sie, ob es nicht erlaubt ist:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

Hier gibt es also kein Richtig oder Falsch. Es liegt an Ihnen, zu entscheiden, was mit Ihren Geschäftsregeln am besten funktioniert.

João Marques
quelle