Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Począwszy od wersji 13.2.0, sterownik JDBC obsługuje typ danych wektorowych . Począwszy od wersji 13.4.0, sterownik obsługuje również podtyp vector(float16). Vector jest również obsługiwany przez funkcje, takie jak parametry z wartością tabeli i narzędzie BulkCopy, z pewnymi ograniczeniami. Na tej stronie przedstawiono różne przypadki użycia typu danych wektora ze sterownikiem JDBC. Aby zapoznać się z omówieniem typów danych wektorowych , zobacz Vector data type (Typ danych wektorowych).
Tworzenie obiektu wektorowego
Klasa microsoft.sql.Vector to niestandardowa implementacja przeznaczona do reprezentowania danych wektorowych w sterowniku JDBC. Zapewnia ona ustrukturyzowany sposób obsługi danych o wysokim wymiarach, w tym serializacji i deserializacji, przy jednoczesnym zapewnieniu zgodności z typem danych wektorowych programu SQL Server. Obiekt wektorowy powinien zawierać liczbę elementów, wskaźnik typu i dane.
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
Sterownik JDBC firmy Microsoft dla programu SQL Server oferuje dwie metody inicjowania obiektu wektorowego, zapewniając elastyczność dla różnych przypadków użycia i danych wejściowych.
Tworzenie obiektu wektorowego z liczbą wymiarów i typem wektora
Konstruktor:
public Vector(int dimensionCount, VectorDimensionType vectorType, Object[] data);
Przykład:
Vector vector = new Vector(3, Vector.VectorDimensionType.FLOAT32, new Float[]{1.0f, 2.0f, 3.0f});
Tworzenie obiektu wektorowego z dokładnością i skalowaniem
Konstruktor:
public Vector(int precision, int scale, Object[] data);
Gdzie parametry są następujące:
- precyzja: liczba wymiarów w wektorze.
- scale: wartość skalowania, która reprezentuje liczbę bajtów na wymiar. 4 bajty reprezentuje FLOAT32.
- data: tablica float[] zawierająca wartości liczbowe w wektorze.
Przykład:
Vector vector = new Vector(3, 4, new Float[]{1.0f, 2.0f, 3.0f});
Wypełnianie i pobieranie tabeli
Oto kilka przykładów kodu, które wypełniają i pobierają dane wektorowe z bazy danych. W przykładach przyjęto założenie, że tabela z kolumną wektorową zdefiniowana w następujący sposób:
CREATE TABLE sampleTable (vector_col vector(3))
Wstaw wartości za pomocą zwykłej instrukcji INSERT:
try (Statement stmt = connection.createStatement()){
stmt.execute("insert into sampleTable values ('[0.1, 2.0, 3.0]')");
}
Wstaw wartości przy użyciu przygotowanego zapytania z parametrem wektora:
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();
}
Wstaw wartość null za pomocą przygotowanej instrukcji i parametru.
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();
}
Odczytywanie wartości wektorów z tabeli:
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 + ")");
}
}
}
Używanie procedur składowanych z wektorem
Z następującą procedurą składowaną:
String sql = "CREATE PROCEDURE " + inputProc +
" @p0 VECTOR(3) OUTPUT AS " +
" SELECT TOP 1 @p0 = col_vector FROM sampleTable ";
Zwróć parametr wyjściowy wektora, korzystając z następującego przykładu:
try (CallableStatement callableStatement = con.prepareCall("{call " + inputProc + " (?) }")) {
callableStatement.registerOutParameter(1, microsoft.sql.Types.VECTOR, 3, 4);
callableStatement.execute();
}
Począwszy od wersji 13.6 przeciążenie o nazwie SQLServerCallableStatement.setObject(String, Object, int, int) i jego wariant forceEncrypt zachowują liczbę wymiarów wektora przekazaną w czwartym argumencie.
Wykorzystanie TVP z wektorem
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();
}
Począwszy od wersji 13.6, sterownik weryfikuje wynegocjowaną obsługę wektorów przed zapisaniem metadanych kolumn TVP. Wektor FLOAT16 wymaga vectorTypeSupport=v2 oraz serwera, który negocjuje wersję 2 wektorów. Sterownik odrzuca wartości TVP typu FLOAT16 w połączeniu w wersji 1 i odrzuca wszystkie natywne wartości wektorowe TVP, gdy vectorTypeSupport=off.
Używanie narzędzia SQLServerBulkCopy z tabeli źródłowej do tabeli docelowej z wektorem
Wektory mogą być używane w poleceniach kopiowania zbiorczego:
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);
}
Używanie funkcji bulkCopy z pliku CSV do tabeli docelowej z wektorem
Wektory można importować z plików CSV.
Wklej następującą zawartość do pliku CSV o nazwie 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);
}
Używanie wektorowego typu danych FLOAT16
FLOAT16 (IEEE 754 half-precision, 16-bitowe) wektory używają 2 bajtów na wymiar zamiast 4, zmniejszając tym samym o połowę wymagane miejsce do magazynowania i umożliwiają maksymalnie 3996 wymiarów na wektor (w porównaniu z 1998 dla FLOAT32) w ramach limitu 8000 bajtów TDS. Ten podtyp jest szczególnie przydatny w przypadku obciążeń sztucznej inteligencji/uczenia maszynowego na dużą skalę, takich jak wyszukiwanie podobieństwa i osadzanie magazynu, w którym ma znaczenie wydajność pamięci.
obsługa wektorów FLOAT16 jest włączona za pośrednictwem istniejącego rozszerzenia funkcji wektorowej (identyfikator FE 0x0E) z uzgadnianiem w wersji 2: klient żąda wersji 2 za pośrednictwem vectorTypeSupport właściwości połączenia, a serwer potwierdza możliwości FLOAT16 w odpowiedzi feature-ack.
Aby użyć wektorów FLOAT16, postępuj zgodnie z tymi samymi wzorcami przedstawionymi w poprzednich przykładach, zastępując element FLOAT32 wartością FLOAT16 oraz wartość skalowania 4 wartością 2. Przykład:
- Użyj
Vector.VectorDimensionType.FLOAT16zamiastVector.VectorDimensionType.FLOAT32. - Użyj skali
2zamiast4podczas konstruowania wektora z dokładnością i skalą. - Zdefiniuj kolumny SQL jako
vector(3, float16)zamiastvector(3).
Oto przykład tworzenia obiektu wektora FLOAT16:
// 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});
Konwertuj wektory między formatami FLOAT16 i FLOAT32
Na serwerach obsługujących konwersję wektorów między typami program SQL Server może niejawnie lub jawnie konwertować między wektorami FLOAT16 i FLOAT32. Przykład:
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;
Wektory źródłowe i docelowe muszą mieć tę samą liczbę wymiarów. Konwersja z FLOAT32 do FLOAT16 może prowadzić do utraty precyzji, ponieważ FLOAT16 ma mniejszy zakres reprezentowanych wartości i mniej bitów znaczących. Wartości zerowe pozostają zerowe po konwersji. Te konwersje mają również zastosowanie do przypisań za pomocą instrukcji przygotowanych, parametrów procedur składowanych, parametrów o wartościach tabelarycznych oraz kopiowania zbiorczego.
Zgodność z poprzednimi wersjami
Jeśli aplikacja nie jest aktualizowana w celu obsługi typu danych wektorowych , sterownik zapewnia zgodność z poprzednimi wersjami, umożliwiając odczyt typów danych wektorowych jako typy zgodne z poprzednimi wersjami. To zachowanie jest kontrolowane za pomocą vectorTypeSupport właściwości parametrów połączenia.
Obsługiwane wartości to off (serwer wysyła typy wektorów jako dane ciągu w formacie JSON), v1 (serwer wysyła typy wektorów FLOAT32 jako dane wektorowe) i v2 (aby włączyć obsługę typów wektorów dla FLOAT16). Domyślna wartość to v1.
Ograniczenia wektora
Aby uzyskać szczegółowe ograniczenia, zobacz Ograniczenia typów danych wektorów.