php - titel - Wie fügt man 'Einfügen, wenn nicht existiert' in MySQL ein?




title tag wordpress (7)

Ich fing an zu googeln und fand diesen article über Mutextabellen.

Ich habe eine Tabelle mit ~ 14 Millionen Datensätzen. Wenn ich mehr Daten im selben Format hinzufügen möchte, gibt es eine Möglichkeit, sicherzustellen, dass der Datensatz, den ich einfügen möchte, nicht bereits existiert, ohne ein Paar Abfragen zu verwenden (dh eine Abfrage zu prüfen und eine einzufügen ist die Ergebnismenge) leer)?

Garantiert eine unique Einschränkung für ein Feld, dass die insert fehlschlägt, wenn sie bereits vorhanden ist?

Es scheint, dass mit nur einer Einschränkung, wenn ich die Einfügung über PHP ausstelle, das Skript krächzt.


Es gibt mehrere Antworten, die beschreiben, wie Sie dies lösen können, wenn Sie einen UNIQUE Index haben, den Sie mit ON DUPLICATE KEY oder INSERT IGNORE . Das ist nicht immer der Fall, und da UNIQUE eine Längenbeschränkung (1000 Byte) hat, können Sie dies möglicherweise nicht ändern. Zum Beispiel musste ich mit Metadaten in WordPress arbeiten ( wp_postmeta ).

Ich habe es schließlich mit zwei Abfragen gelöst:

UPDATE wp_postmeta SET meta_value = ? WHERE meta_key = ? AND post_id = ?;
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) SELECT DISTINCT ?, ?, ? FROM wp_postmeta WHERE NOT EXISTS(SELECT * FROM wp_postmeta WHERE meta_key = ? AND post_id = ?);

Abfrage 1 ist eine reguläre UPDATE Abfrage ohne Auswirkung, wenn der betreffende Datensatz nicht vorhanden ist. Abfrage 2 ist ein INSERT das von einem NOT EXISTS , dh das INSERT wird nur ausgeführt, wenn das Dataset nicht existiert.


Hier ist eine PHP-Funktion, die nur dann eine Zeile einfügt, wenn alle angegebenen Spaltenwerte nicht bereits in der Tabelle vorhanden sind.

  • Wenn sich eine der Spalten unterscheidet, wird die Zeile hinzugefügt.

  • Wenn die Tabelle leer ist, wird die Zeile hinzugefügt.

  • Wenn eine Zeile existiert, in der alle angegebenen Spalten die angegebenen Werte haben, wird die Zeile nicht hinzugefügt.

    function insert_unique($table, $vars)
    {
      if (count($vars)) {
        $table = mysql_real_escape_string($table);
        $vars = array_map('mysql_real_escape_string', $vars);
    
        $req = "INSERT INTO `$table` (`". join('`, `', array_keys($vars)) ."`) ";
        $req .= "SELECT '". join("', '", $vars) ."' FROM DUAL ";
        $req .= "WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE ";
    
        foreach ($vars AS $col => $val)
          $req .= "`$col`='$val' AND ";
    
        $req = substr($req, 0, -5) . ") LIMIT 1";
    
        $res = mysql_query($req) OR die();
        return mysql_insert_id();
      }
    
      return False;
    }
    

Beispielverwendung:

<?php
insert_unique('mytable', array(
  'mycolumn1' => 'myvalue1',
  'mycolumn2' => 'myvalue2',
  'mycolumn3' => 'myvalue3'
  )
);
?>

Versuche Folgendes:

IF (SELECT COUNT(*) FROM beta WHERE name = 'John' > 0)
  UPDATE alfa SET c1=(SELECT id FROM beta WHERE name = 'John')
ELSE
BEGIN
  INSERT INTO beta (name) VALUES ('John')
  INSERT INTO alfa (c1) VALUES (LAST_INSERT_ID())
END

Versuchen:

// Check if exist cod = 56789
include "database.php";

$querycheck = mysql_query ("SELECT * FROM `YOURTABLE` WHERE `xxx` = '56789';");
$countrows = mysql_num_rows($querycheck);
if($countrows == '1')
{
  // Exist 
}
else
{
 // .... Not exist
}

Oder Sie können tun:

// Check if exist cod = 56789
include "database.php";

$querycheck = mysql_query ("SELECT * FROM `YOURTABLE` WHERE `xxx` = '56789';");
$countrows = mysql_num_rows($querycheck);
while($result = mysql_fetch_array($querycheck))
{
    $xxx = $result['xxx'];
    if($xxx == '56789')
    {
      // Exist
    }
    else
    {
      // Not exist
    }
}

Diese Methode ist schnell und einfach. Zur Verbesserung der Geschwindigkeit der Abfrage in Ihren großen Tabellen INDEX-Spalten 'xxx' (in meinem Beispiel).


Nach dem Duplicate Key Update , oder das Einfügen von Ignore kann eine brauchbare Lösung mit MySQL sein.

Beispiel für die Aktualisierung des duplizierten Schlüssels auf der Basis von mysql.com

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE table SET c=c+1 WHERE a=1;

Beispiel für das Einfügen ignorieren basierend auf mysql.com

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

Oder:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

Oder:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

Replace könnte für Sie arbeiten.


REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;

Wenn der Datensatz existiert, wird er überschrieben. Wenn es noch nicht existiert, wird es erstellt.





primary-key