Pengantar
Pekerjaan sehari-hari jarang membutuhkan penyimpanan data biner langsung ke kolom database. Namun, ini sangat berguna dalam beberapa kasus.
Berlawanan dengan pendapat umum, array byte dapat membantu secara signifikan lebih dari sekadar menyimpan objek biner besar (dokumen, multimedia, dll.). Juga, mereka dapat digunakan untuk menyimpan nilai hash dan data sampel untuk pencarian yang lebih cepat/analisis tingkat tinggi. Atau, mereka mungkin berisi byte yang berada dalam status ON/OFF di beberapa relai elektronik. Segera setelah kita mulai berpikir tentang data perangkat keras yang disimpan dalam database, aplikasi menjadi lebih jelas.
Tidak seperti tipe data VARCHAR di mana Anda harus mengurus halaman susunan dan kode, tipe data biner adalah rangkaian byte (kadang-kadang disebut array byte dalam bahasa pemrograman berorientasi objek), baik ukuran tetap (BINAR ) atau variabel (VARBINAR ).
Untuk memahami detail jenis biner dengan lebih baik, pertama-tama kita akan melakukan pengenalan singkat tentang bilangan heksadesimal, yang merupakan cara data ini disimpan secara internal.
Bilangan Heksadesimal
Jika Anda melewatkan kelas tentang bilangan heksadesimal di sekolah menengah, pengantar yang bagus dapat ditemukan di halaman Wikipedia khusus. Di sana, Anda dapat membiasakan diri dengan format penomoran ini.
Untuk memahami artikel ini, penting untuk diketahui bahwa SQL Server Management Studio menampilkan data biner dalam format heksadesimal dengan awalan “0x”.
Tidak ada perbedaan besar antara format penomoran heksadesimal dan desimal. Format heksadesimal menggunakan tanda basis-16 (0-9 dan A-F) sebagai ganti basis-10 dari notasi desimal (0-9). Nilai A-F adalah angka 10-15 dari notasi bilangan desimal.
Inilah sebabnya mengapa kami menggunakan notasi heksadesimal. Karena satu byte berisi 8 bit, memungkinkan 256 bilangan bulat diskrit, adalah bermanfaat untuk menyajikan byte dalam format hex. Jika kami menargetkan rentang 0-256, ini direpresentasikan sebagai 00-FF dalam notasi heksadesimal. Awalan di studio Manajemen adalah untuk kejelasan membaca, untuk menekankan bahwa kami menunjukkan angka heksadesimal dan bukan default nilai desimal.
Konversi Nilai Manual Menggunakan CAST()
Karena nilai biner, dalam arti sempit, adalah string, kita dapat mengonversinya dari format angka ke karakter menggunakan CAST atau KONVERSI Metode SQL.
Lihat contoh yang menggunakan CAST metode:
SELECT CAST('HexTest' AS VARBINARY);
SELECT CAST(0x48657854657374 AS VARCHAR);
Menggunakan Gaya Konversi dengan CONVERT()
KONVERSI() metode, tidak seperti CAST() , memiliki opsi tambahan untuk menggunakan gaya konversi.
Gaya konversi adalah template untuk aturan yang digunakan dalam proses konversi. KONVERSI() sebagian besar digunakan dalam operasi tanggal/waktu. Ketika data dalam format non-standar, dapat digunakan dalam konversi nilai biner. Perhatikan bahwa tipe data biner tidak mendukung konversi tipe data otomatis tanpa nilai parameter yang tepat. Kemudian SQL Server akan mengeluarkan pengecualian.
Jika kita melihat CONVERT() definisi metode, kami melihatnya membutuhkan dua parameter wajib dan satu parameter opsional.
Parameter pertama adalah tipe data target, dan yang kedua adalah nilai dari mana kita ingin mengonversi. Parameter ketiga, dalam kasus kami, dapat menilai 1 atau 2 . Nilai 1 artinya CONVERT() harus mempertimbangkan string input sebagai string heksadesimal dalam format teks, dan nilai 2 berarti Anda ingin melewati 0x awalan.
Lihat contoh yang menampilkan perilaku tersebut:
DECLARE @MyString NVARCHAR(500)='0x48657854657374';
SELECT CONVERT(VARBINARY(MAX), @MyString );
-- String value is directly converted to binary value - we wanted is to change the datatype
-- and not convert "0x.." prefix to the hexadecimal value
SELECT CONVERT(VARBINARY(MAX), @MyString, 1);
Perbedaan Antara BINARY dan VARBINARY
Dengan data biner, kita dapat menggunakan dua jenis tipe data – ukuran tetap dan ukuran variabel. Atau, mereka adalah BINARY dan VARBINARY.
Jika kita menggunakan variabel ukuran tetap, konten selalu diperluas ke ukuran yang ditentukan dengan padding 0x00 … – tidak ada bantalan dalam panjang variabel. Menggunakan operasi penjumlahan pada variabel-variabel ini tidak ada penambahan yang dieksekusi. Nilai ditambahkan satu sama lain. Sama halnya dengan tipe string.
Untuk mendemonstrasikan perilaku awalan, kita akan menggunakan dua contoh sederhana dengan operasi penjumlahan biner:
SELECT CAST('T' AS BINARY(1)) + CAST('e' AS BINARY(1)) + CAST('s' AS BINARY(1)) + CAST('t' AS BINARY(1));
SELECT CAST('T' AS BINARY(2)) + CAST('e' AS BINARY(2)) + CAST('s' AS BINARY(2)) + CAST('t' AS BINARY(2));
Setiap nilai dalam pernyataan BINARY(2) diberi postfix dengan 0x00 nilai.
Menggunakan Nilai Integer dengan Tipe Data Biner
SQL Server hadir dengan metode bawaan untuk mengonversi antara tipe numerik dan tipe biner. Kami menunjukkan ini di mana kami mengubah Uji string ke dalam format biner, lalu kembali ke format BIGINT, tanpa menggunakan fungsi ASCII():
SELECT CAST('Test' AS VARBINARY(MAX));
SELECT CAST(CAST('Test' AS VARBINARY(MAX)) AS BIGINT);
Konversi Sederhana Antara Nilai Karakter dan Heksadesimal
Untuk mengonversi antara nilai piagam dan heksadesimal, akan berguna untuk menulis fungsi kustom yang akan melakukan operasi ini secara konsisten. Salah satu pendekatan yang mungkin adalah di bawah ini:
-- DROP FUNCTION dbo.FN_CH_HEX(@InputValue CHAR(1)
CREATE OR ALTER FUNCTION dbo.FN_CH_HEX(@InputValue CHAR(1))
RETURNS CHAR(2)
AS
BEGIN
RETURN(CONVERT(CHAR(2), CAST(@InputValue AS BINARY(1)), 2));
END;
-- SELECT dbo.FN_CH_HEX('A')
Kali ini kami menggunakan nilai parameter 2 di CONVERT() fungsi. Ini menunjukkan bahwa operasi ini tidak boleh dipetakan ke kode ASCII dan ditampilkan tanpa 0x… awalan.
Contoh Studi Kasus:Menyimpan Foto dalam Jenis Biner SQL Server
Kami biasanya mendekati masalah ini dengan menerapkan aplikasi windows/web khusus atau menulis paket SSIS khusus dengan kode C#. Dalam contoh ini, saya hanya akan menggunakan bahasa SQL. Ini bisa lebih berguna jika Anda tidak memiliki akses ke alat front-end database.
Untuk menyimpan gambar dalam tabel database, kita perlu membuat tabel yang akan menampungnya. Tabel harus menyertakan kolom yang berisi nama gambar dan konten biner gambar:
-- DROP TABLE T_BINARY_DATA
CREATE TABLE T_BINARY_DATA
(
PICTURE_ID INT IDENTITY(1,1) PRIMARY KEY,
PICTURE_NAME NVARCHAR(100),
PICTURE_FILE_NAME NVARCHAR(500),
PICTURE_DATA VARBINARY(MAX)
)
GO
Untuk mengaktifkan pemuatan data biner ke instance SQL Server, kita perlu mengkonfigurasi server dengan dua opsi:
- Aktifkan opsi Prosedur Otomatisasi OLE
- Memberikan hak istimewa BulkAdmin kepada pengguna yang menjalankan proses impor gambar.
Skrip di bawah ini akan melakukan tugas di bawah pengguna SQL Server dengan hak istimewa tinggi:
USE MASTER
GO
EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO
-- Add 'bulkadmin' to the correct user
ALTER SERVER ROLE [bulkadmin] ADD MEMBER [NT AUTHORITY\SYSTEM]
GO
Sekarang kita dapat mulai menulis prosedur impor dan ekspor:
-- DROP PROCEDURE dbo.proc_ImportBinary
-- DROP PROCEDURE dbo.proc_ExportBinary
CREATE PROCEDURE dbo.proc_ImportBinary
(
@PICTURE_NAME NVARCHAR(100)
, @FOLDER_PATH NVARCHAR(500)
, @PICTURE_FILE_NAME NVARCHAR(500)
)
AS
BEGIN
DECLARE @OutputPath NVARCHAR(4000);
DECLARE @TSQLDYN NVARCHAR(4000);
SET @OutputPath = CONCAT(@OutputPath,'\',@PICTURE_FILE_NAME)
SET @TSQLDYN = 'INSERT INTO T_BINARY_DATA(PICTURE_NAME,PICTURE_FILE_NAME,PICTURE_DATA) '
+ 'SELECT ' + '''' + @PICTURE_NAME + '''' + ',' + '''' + @PICTURE_FILE_NAME + '''' + ', * '
+ ' FROM Openrowset( Bulk ' + '''' + @OutputPath + '''' + ', Single_Blob) as img'
EXEC (@TSQLDYN)
END
GO
CREATE PROCEDURE dbo.proc_ExportBinary (
@PICTURE_NAME NVARCHAR(100)
, @FOLDER_PATH NVARCHAR(500)
, @PICTURE_FILE_NAME NVARCHAR(500)
)
AS
BEGIN
DECLARE @Binary VARBINARY (max);
DECLARE @OutputPath NVARCHAR(4000);
DECLARE @Obj INT
SELECT @Binary = (
SELECT CONVERT(VARBINARY(max), PICTURE_DATA , 1)
FROM T_BINARY_DATA
WHERE PICTURE_NAME = @PICTURE_NAME
);
SET @OutputPath = CONCAT(@FOLDER_PATH, '\', @PICTURE_FILE_NAME);
BEGIN TRY
EXEC sp_OACreate 'ADODB.Stream', @Obj OUTPUT;
EXEC sp_OASetProperty @Obj ,'Type',1;
EXEC sp_OAMethod @Obj,'Open';
EXEC sp_OAMethod @Obj,'Write', NULL, @Binary;
EXEC sp_OAMethod @Obj,'SaveToFile', NULL, @OutputPath, 2;
EXEC sp_OAMethod @Obj,'Close';
EXEC sp_OADestroy @Obj;
END TRY
BEGIN CATCH
EXEC sp_OADestroy @Obj;
END CATCH
SET NOCOUNT OFF
END
GO
Sekarang kita dapat menggunakan prosedur ini dari aplikasi klien mana pun dengan cara yang sangat sederhana.
Bayangkan kita memiliki gambar di C:\Pictures\Inp map. Untuk memuat gambar-gambar ini, kita perlu menjalankan kode berikut:
-- Load picture to table row
exec dbo.proc_ImportBinary ‘MyPic’, ‘C:\Pictures\Inp’, ‘MyPic.jpg’
Dengan cara yang sama kita dapat mengekspor data, ke C:\Pictures\Out map:
exec dbo.proc_ExportBinary ‘MyPic’, ‘C:\Pictures\Out’, ‘MyPic.jpg’
Kesimpulan
Pilihan antara objek biner atau cara alternatif untuk menyimpan data biner dalam database (misalnya, menyimpan jalur file dalam database dan mengambilnya dari penyimpanan disk/cloud) bergantung pada banyak faktor.
Aturan umumnya adalah jika file berukuran kurang dari 256 kilobyte, Anda harus menyimpannya di kolom VARBINARY. Jika file biner lebih besar dari satu megabyte, Anda harus menyimpannya di sistem file. Jika Anda memiliki FILESTREAM yang tersedia di SQL Server versi 2008 dan yang lebih baru, file tersebut akan tetap berada di bawah kendali transaksional sebagai bagian logis dari database.
Jika Anda memutuskan untuk menyimpan file biner di tabel SQL Server, gunakan tabel terpisah hanya untuk konten biner. Kemudian Anda dapat mengoptimalkan lokasi penyimpanannya dan mengakses mesin, mungkin menggunakan File dan FileGroups terpisah untuk tabel ini. Informasi terperinci tersedia di artikel resmi Microsoft.
Bagaimanapun, uji kedua pendekatan dan gunakan yang paling sesuai dengan kebutuhan Anda.