Vectorgegevenstype gebruiken met het JDBC-stuurprogramma

JDBC-stuurprogramma downloaden

Vanaf versie 13.2.0 ondersteunt het JDBC-stuurprogramma het vectorgegevenstype . Vanaf versie 13.4.0 ondersteunt het stuurprogramma ook het vector(float16) -subtype. Vector wordt ook ondersteund met functies zoals Table-Valued Parameters en BulkCopy, met enkele beperkingen. Op deze pagina ziet u verschillende use cases van het vectorgegevenstype met het JDBC-stuurprogramma. Zie Vector-gegevenstype voor een overzicht van vectorgegevenstypen.

Een vectorobject maken

De klasse microsoft.sql.Vector is een aangepaste implementatie die is ontworpen om vectorgegevens in het JDBC-stuurprogramma weer te geven. Het biedt een gestructureerde manier om high-dimensionale gegevens te verwerken, waaronder serialisatie en deserialisatie, en tegelijkertijd compatibiliteit met het vectorgegevenstype van SQL Server te garanderen. Het vectorobject moet het aantal elementen, het typeindicator en de gegevens bevatten.

public enum VectorDimensionType {
        FLOAT32 // 32-bit (single precision) float
}

private VectorDimensionType vectorType; // The type of values in the data array
private int dimensionCount; // Number of dimensions in the vector
private Object[] data; // An array containing the vector's numerical values

Het Microsoft JDBC-stuurprogramma voor SQL Server biedt twee methoden om een vectorobject te initialiseren, wat flexibiliteit biedt voor verschillende use cases en invoergegevens.

Een vectorobject maken met dimensieaantal en vectortype

Constructor

public Vector(int dimensionCount, VectorDimensionType vectorType, Object[] data);

Voorbeeld:

Vector vector = new Vector(3, Vector.VectorDimensionType.FLOAT32, new Float[]{1.0f, 2.0f, 3.0f});

Een vectorobject maken met precisie en schaal

Constructor

public Vector(int precision, int scale, Object[] data);

Waar de parameters zijn:

  • precisie: het aantal dimensies in de vector.
  • schaal: De schaalwaarde, die het aantal bytes per dimensie aangeeft. 4 bytes vertegenwoordigt een FLOAT32.
  • gegevens: Een float[] matrix met de numerieke waarden in de vector.

Voorbeeld:

Vector vector = new Vector(3, 4, new Float[]{1.0f, 2.0f, 3.0f});

Een tabel vullen en ophalen

Hier volgen enkele codevoorbeelden waarmee vectorgegevens uit een database worden ingevuld en opgehaald. In de voorbeelden wordt ervan uitgegaan dat een tabel met een vectorkolom als volgt is gedefinieerd:

CREATE TABLE sampleTable (vector_col vector(3))

Waarden invoegen met een gewone INSERT instructie:

try (Statement stmt = connection.createStatement()){
    stmt.execute("insert into sampleTable values ('[0.1, 2.0, 3.0]')");
}

Voeg waarden in met een voorbereide instructie en een vectorparameter :

Vector vector = new Vector(3, Vector.VectorDimensionType.FLOAT32, new Float[]{1.0f, 2.0f, 3.0f});
try (PreparedStatement preparedStatement = con.prepareStatement("insert into sampleTable values (?)")) {
    preparedStatement.setObject(1, vector, microsoft.sql.Types.VECTOR);
    preparedStatement.execute();
}

Voeg een null-waarde in met een voorbereide instructie en een parameter:

Vector vector = new Vector(1, Vector.VectorDimensionType.FLOAT32, null);
try (PreparedStatement preparedStatement = con.prepareStatement("insert into sampleTable values (?)")) {
    preparedStatement.setObject(1, vector, microsoft.sql.Types.VECTOR);
    preparedStatement.execute();
}
try (PreparedStatement preparedStatement = con.prepareStatement("insert into sampleTable values (?)")) {
    preparedStatement.setObject(1, null)
    preparedStatement.execute();
}

Vectorwaarden uit een tabel lezen:

try (SQLServerResultSet resultSet = (SQLServerResultSet) stmt.executeQuery("select * from sampleTable")) {
    assertTrue(resultSet.next(), "No result found for inserted vector.");
    ResultSetMetaData metaData = resultSet.getMetaData();
    int columnCount = metaData.getColumnCount();

    while (resultSet.next()) {
        for (int i = 1; i <= columnCount; i++) {
            String columnName = metaData.getColumnName(i);
            int columnType = metaData.getColumnType(i); // from java.sql.Types

            Object value = null;
            switch (columnType) {
                case Types.VARCHAR:
                case Types.NVARCHAR:
                    value = resultSet.getString(i);
                    break;
                case microsoft.sql.Types.VECTOR:
                    value = resultSet.getObject(i, microsoft.sql.Vector.class);
            }

            System.out.println(columnName + " = " + value + " (type: " + columnType + ")");
        }
    }
}

Opgeslagen procedures gebruiken met vector

Met de volgende opgeslagen procedure:

String sql = "CREATE PROCEDURE " + inputProc +
             " @p0 VECTOR(3) OUTPUT AS " +
             " SELECT TOP 1 @p0 = col_vector FROM sampleTable ";

Retourneer een vectoruitvoerparameter met het volgende voorbeeld:

try (CallableStatement callableStatement = con.prepareCall("{call " + inputProc + " (?) }")) {
    callableStatement.registerOutParameter(1, microsoft.sql.Types.VECTOR, 3, 4);
    callableStatement.execute();
}

Vanaf versie 13.6 behouden de overload met de naam SQLServerCallableStatement.setObject(String, Object, int, int) en de bijbehorende variant forceEncrypt het aantal vectordimensies dat via het vierde argument wordt opgegeven.

TVP gebruiken met vector

Vector vector = new Vector(3, Vector.VectorDimensionType.FLOAT32, new Float[]{1.0f, 2.0f, 3.0f});
SQLServerDataTable tvp = new SQLServerDataTable();
tvp.addColumnMetadata("vector_col", microsoft.sql.Types.VECTOR);
tvp.addRow(vector);

try (SQLServerPreparedStatement preparedStatement = (SQLServerPreparedStatement) con.prepareStatement( "insert into sampleTable select * from (?)")) {
    pstmt.setStructured(1, TVP_NAME, tvp);
    pstmt.execute();
}

Vanaf versie 13.6 valideert de driver onderhandelde vectorondersteuning voordat de metadata van de TVP-kolom wordt geschreven. Een FLOAT16-vector vereist vectorTypeSupport=v2 en een server die vectorversie 2 ondersteunt. De driver wijst FLOAT16 TVP-waarden af op een versie 1-verbinding en weigert alle native vector TVP-waarden wanneer vectorTypeSupport=off.

SQLServerBulkCopy van brontabel naar doeltabel gebruiken met vector

Vectoren kunnen worden gebruikt in opdrachten voor bulksgewijs kopiëren:

Vector vector = new Vector(3, Vector.VectorDimensionType.FLOAT32, new Float[]{1.0f, 2.0f, 3.0f});
try (Statement stmt = con.createStatement();
        SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(con)) {

        stmt.executeUpdate("create table destinationTable (vector_col vector(3))");

        bulkCopy.setDestinationTableName("destinationTable");
        bulkCopy.writeToServer(vector);
    }

BulkCopy van CSV-bestand gebruiken naar doeltabel met vector

Vectoren kunnen worden geïmporteerd uit CSV-bestanden.

Plak de volgende inhoud in een CSV-bestand met de naam vectors.csv:

vector_col
"[1.0,2.0,3.0]"
"[4.0,5.0,6.0]"
try (Statement stmt = con.createStatement();
    SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(con);
    SQLServerBulkCSVFileRecord fileRecord = new SQLServerBulkCSVFileRecord("vectors.csv", null, ",", true)) {

        stmt.executeUpdate("create table destinationTable (vector_col vector(3))");

        // Add column metadata for the CSV file
        fileRecord.addColumnMetadata(1, "vector_col", microsoft.sql.Types.VECTOR, 3, 4);
        fileRecord.setEscapeColumnDelimitersCSV(true);

        bulkCopy.setDestinationTableName("destinationTable");
        bulkCopy.writeToServer(fileRecord);
}

Vector FLOAT16 gegevenstype gebruiken

FLOAT16 (IEEE 754 halve-precisie, 16-bits) vectoren gebruiken 2 bytes per dimensie in plaats van 4, waarbij de opslagvoetafdruk wordt gehalveerd en maximaal 3.996 dimensies per vector (vs. 1998 voor FLOAT32) binnen de TDS-limiet van 8.000 bytes kunnen worden ondersteund. Dit subtype is vooral waardevol voor grootschalige AI/ML-workloads, zoals overeenkomsten zoeken en insluiten van opslag waar geheugenefficiëntie belangrijk is.

FLOAT16 vectorondersteuning wordt ingeschakeld via de bestaande functieverlenging (FE-id 0x0E) met een handshake van versie 2: de client vraagt v2 aan via de verbindingseigenschap vectorTypeSupport, en de server bevestigt de FLOAT16 ondersteuningsmogelijkheid in het functie-ack-antwoord.

Als u FLOAT16 vectoren wilt gebruiken, volgt u dezelfde patronen die in de voorgaande voorbeelden worden weergegeven en vervangt u door FLOAT32FLOAT16 en de schaalwaarde 4 door 2. Voorbeeld:

  • Gebruik Vector.VectorDimensionType.FLOAT16 in plaats van Vector.VectorDimensionType.FLOAT32.
  • Gebruik een schaal van 2 in plaats van 4 bij het maken van een vector met precisie en schaal.
  • SQL-kolommen definiëren als vector(3, float16) in plaats van vector(3).

Hier volgt een voorbeeld van het maken van een FLOAT16 vectorobject:

// Using dimension count and vector type
Vector vector = new Vector(3, Vector.VectorDimensionType.FLOAT16, new Float[]{1.0f, 2.0f, 3.0f});

// Using precision and scale (2 bytes = FLOAT16)
Vector vector = new Vector(3, 2, new Float[]{1.0f, 2.0f, 3.0f});

Converteer tussen FLOAT16 en FLOAT32 vectoren

Op servers die cross-type vectorconversie ondersteunen, kan SQL Server impliciet of expliciet omzetten tussen FLOAT16 en FLOAT32 vectoren. Voorbeeld:

INSERT INTO float32Table (vector_col)
SELECT vector_col FROM float16Table;

SELECT CAST(vector_col AS VECTOR(3, float32))
FROM float16Table;

SELECT CONVERT(VECTOR(3, float16), vector_col)
FROM float32Table;

De bron- en bestemmingsvectoren moeten hetzelfde aantal dimensies hebben. Het omrekenen van FLOAT32 naar FLOAT16 kan precisie verliezen omdat FLOAT16 een kleiner vertegenwoordigbaar bereik en minder significante bits heeft. Nulwaarden blijven na de omzetting nul. Deze conversies zijn ook van toepassing op toewijzingen via voorbereide statements, parameters van opgeslagen procedures, tabelwaardeparameters en bulkkopie.

Compatibiliteit met eerdere versies

Als een toepassing niet wordt bijgewerkt om het vectorgegevenstype te verwerken, biedt het stuurprogramma compatibiliteit met eerdere versies doordat vectorgegevenstypen als achterwaarts compatibele typen kunnen worden gelezen. Dit gedrag wordt beheerd met de eigenschap vectorTypeSupport van de verbindingsreeks. Ondersteunde waarden zijn off (server verzendt vectortypen als tekenreeksgegevens in JSON-indeling), v1 (server verzendt vectortypen van FLOAT32 als vectorgegevens) en v2 (om vectortypeondersteuning voor FLOAT16 in te schakelen). De standaardwaarde is v1.

Beperkingen van vector

Zie Vector-gegevenstypebeperkingen voor gedetailleerde beperkingen.