2 Stimmen

C# und SQLServer normalisieren großer Sets von URLs

Ich habe viele Tabellen in der Datenbank, die mindestens eine Spalte enthalten, die eine URL enthält. Und diese werden häufig in der gesamten Datenbank wiederholt. Deshalb normalisiere ich sie in eine dedizierte Tabelle und verwende nur numerische IDs, wo ich sie brauche. Ich muss sie oft verknüpfen, daher sind numerische IDs viel besser als vollständige Zeichenfolgen.

In MySql + C++ habe ich früher zum Einfügen vieler URLs in einem Schlag Multi-Row INSERT IGNOREs oder mysql_set_local_infile_handler() verwendet. Dann habe ich mit IN () die IDs im Batch zurück aus der Datenbank gezogen.

In C# + SQLServer habe ich festgestellt, dass es eine SqlBulkCopy-Klasse gibt, die sehr nützlich und schnell beim Masseneinfügen ist. Aber ich brauche auch eine Massenauswahl, um die URL-IDs nach dem Einfügen zu lösen. Gibt es eine solche Hilfsklasse, die genauso funktioniert wie SELECT WHERE IN (viele, urls, hier)?

Oder haben Sie eine bessere Idee, um URLs in C# auf konsistente Weise in Zahlen umzuwandeln? Ich dachte daran, die URLs mit crc32 oder crc64 zu hashen, aber ich mache mir Sorgen über Kollisionen. Es würde mich nicht stören, wenn Kollisionen selten sind, aber wenn nicht... wäre es ein Problem.

PS: Es geht um zig Millionen URLs, um eine Vorstellung von der Größenordnung zu erhalten.

PS: Für grundlegende Großeinfügung ist SQLBulkCopy schneller als SqlDbType.Structured. Außerdem verfügt es über das SqlRowsCopied-Ereignis für eine Statusverfolgungsrückruf.

2voto

Marcel N. Punkte 13388

Es gibt sogar einen besseren Weg als SQLBulkCopy.

Es heißt Strukturierte Parameter und es ermöglicht Ihnen, einen tabellenwertigen Parameter an eine gespeicherte Prozedur oder Abfrage über ADO.NET zu übergeben.

Es gibt Codebeispiele im Artikel, daher werde ich nur hervorheben, was Sie tun müssen, um es zum Laufen zu bringen:

  1. Erstellen Sie einen benutzerdefinierten Tabellentyp in der Datenbank. Sie können ihn UrlTable nennen
  2. Richten Sie eine SP oder Abfrage ein, die das SELECT durchführt, indem sie mit einer Tabellenvariablen oder dem Typ UrlTable verbunden wird
  3. In Ihrem Back-End-Code (C#) erstellen Sie ein DataTable mit der gleichen Struktur wie UrlTable, füllen Sie es mit URLs und übergeben Sie es als strukturierten Parameter an einen SqlCommand. Beachten Sie, dass die Übereinstimmung der Spaltenreihenfolge zwischen der Daten Tabelle und der Tabellenart entscheidend ist.

Was ADO.NET im Hintergrund macht (wenn Sie die Abfrage im Profiler sehen können) ist, dass es vor der Abfrage eine Variable vom Typ UrlTable deklariert und sie (INSERT-Anweisungen) mit dem füllt, was Sie im strukturierten Parameter übergeben.

Abgesehen davon können Sie mit tabellenwertigen Parametern in SQL (JOIN, SELECT usw.) praktisch alles machen.

0voto

Panayotis Punkte 1743

Ich denke, du könntest die IGNORE_DUP_KEY Option auf deinem Index verwenden. Wenn du IGNORE_DUP_KEY = ON für den Index der URL-Spalte setzt, werden die doppelten Werte einfach ignoriert und der Rest wird entsprechend eingefügt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X