Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Mengganti Partisi Tabel di SQL Server:Sebuah Panduan

Pengantar

Beberapa tahun yang lalu kami ditugaskan dengan persyaratan bisnis untuk data kartu dalam format tertentu untuk tujuan sesuatu yang disebut "rekonsiliasi". Idenya adalah untuk menyajikan data dalam tabel ke aplikasi yang akan mengkonsumsi dan memproses data yang akan memiliki periode retensi enam bulan. Kami harus membuat database baru untuk kebutuhan bisnis ini dan kemudian membuat tabel inti sebagai tabel yang dipartisi. Proses yang dijelaskan di sini adalah proses yang kami gunakan untuk memastikan bahwa data yang lebih lama dari enam bulan dipindahkan dari tabel dengan cara yang bersih.

Sedikit Tentang Partisi

Tabel Partisi adalah teknologi database yang memungkinkan Anda untuk menyimpan data milik satu unit logis (tabel) sebagai satu set partisi yang akan duduk di struktur fisik yang terpisah – file data – melalui lapisan abstraksi yang disebut File Groups di SQL Server. Proses pembuatan Tabel Partisi ini melibatkan dua objek utama:

Fungsi Partisi :Fungsi Partisi mendefinisikan bagaimana baris tabel yang dipartisi dipetakan berdasarkan nilai kolom tertentu (Kolom Partisi). Tabel yang dipartisi dapat didasarkan pada daftar atau rentang. Untuk tujuan kasus penggunaan kami (hanya mempertahankan data selama enam bulan), kami menggunakan Partisi Rentang . Fungsi Partisi dapat didefinisikan sebagai RANGE RIGHT atau RANGE LEFT. Kami menggunakan RANGE RIGHT seperti yang ditunjukkan pada kode di Listing 1 yang berarti nilai batas akan berada di sisi kanan interval nilai batas ketika nilai diurutkan dalam urutan menaik dari kiri ke kanan.

-- Listing 1: Create a Partition Function
USE [post_office_history]
GO
CREATE PARTITION FUNCTION
PostTranPartFunc (datetime)
AS RANGE RIGHT
FOR VALUES 
('20190201'
,'20190301'
,'20190401'
,'20190501'
,'20190601'
,'20190701'
,'20190801'
,'20190901'
,'20191001'
,'20191101'
,'20191201'
)
GO

Skema Partisi :Skema partisi didasarkan pada Fungsi Partisi dan menentukan di mana baris struktur fisik milik setiap partisi akan ditempatkan. Ini dicapai dengan memetakan baris seperti itu ke grup file. Daftar 2 menunjukkan kode untuk membuat Skema Partisi. Sebelum membuat Skema Partisi, grup file yang akan dirujuk harus ada.

-- Listing 2: Create Partition Scheme --

-- Step 1: Create Filegroups --

USE [master]
GO
ALTER DATABASE [post_office_history] ADD FILEGROUP [JAN]
ALTER DATABASE [post_office_history] ADD FILEGROUP [FEB]
ALTER DATABASE [post_office_history] ADD FILEGROUP [MAR]
ALTER DATABASE [post_office_history] ADD FILEGROUP [APR]
ALTER DATABASE [post_office_history] ADD FILEGROUP [MAY]
ALTER DATABASE [post_office_history] ADD FILEGROUP [JUN]
ALTER DATABASE [post_office_history] ADD FILEGROUP [JUL]
ALTER DATABASE [post_office_history] ADD FILEGROUP [AUG]
ALTER DATABASE [post_office_history] ADD FILEGROUP [SEP]
ALTER DATABASE [post_office_history] ADD FILEGROUP [OCT]
ALTER DATABASE [post_office_history] ADD FILEGROUP [NOV]
ALTER DATABASE [post_office_history] ADD FILEGROUP [DEC]
GO


-- Step 2: Add Data Files to each Filegroup --

USE [master]
GO
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_01', FILENAME = N'E:\MSSQL\DATA\post_office_history_part_01.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [JAN]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_02', FILENAME = N'E:\MSSQL\DATA\post_office_history_part_02.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [FEB]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_03', FILENAME = N'E:\MSSQL\DATA\post_office_history_part_03.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [MAR]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_04', FILENAME = N'E:\MSSQL\DATA\post_office_history_part_04.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [APR]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_05', FILENAME = N'E:\MSSQL\DATA\post_office_history_part_05.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [MAY]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_06', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_06.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [JUN]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_07', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_07.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [JUL]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_08', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_08.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [AUG]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_09', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_09.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [SEP]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_10', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_10.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [OCT]
GO
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_09', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_11.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [NOV]
ALTER DATABASE [post_office_history] ADD FILE (NAME = N'post_office_history_part_10', FILENAME = N'G:\MSSQL\DATA\post_office_history_part_12.ndf', SIZE = 2097152KB, FILEGROWTH = 1048576KB) TO FILEGROUP [DEC]
GO


-- Step 3: Create Partition Scheme --

PRINT 'creating partition scheme ...'
GO

USE [post_office_history]
GO
CREATE PARTITION SCHEME PostTranPartSch 
AS PARTITION PostTranPartFunc TO
(
JAN,
FEB,
MAR,
APR,
MAY,
JUN,
JUL,
AUG,
SEP,
OCT,
NOV,
DEC
)
GO

Perhatikan bahwa untuk N partisi, akan selalu ada N-1 batasan. Kehati-hatian harus diambil ketika mendefinisikan Filegroup pertama dalam Skema Partisi. Batas pertama yang tercantum dalam Fungsi Partisi akan terletak di antara Filegroups pertama dan kedua sehingga nilai batas ini (20190201) akan berada di partisi kedua (FEB). Selain itu, sebenarnya dimungkinkan untuk menempatkan semua partisi dalam satu filegroup tetapi kami telah memilih filegroup yang terpisah dalam kasus ini.

Membuat Tangan Kita Kotor

Jadi, mari selami tugas mengganti partisi!

Hal pertama yang perlu kita lakukan adalah menentukan dengan tepat bagaimana data kita didistribusikan di antara partisi sehingga kita dapat mengetahui partisi mana yang ingin kita alihkan. Biasanya kita akan mengganti partisi terlama.

-- Listing 3: Check Data Distribution in Partitions --

USE POST_OFFICE_HISTORY
GO
SELECT $PARTITION.POSTTRANPARTFUNC(DATETIME_TRAN_LOCAL)
			AS [PARTITION NUMBER]
	, MIN(DATETIME_TRAN_LOCAL) AS [MIN DATE]
	, MAX(DATETIME_TRAN_LOCAL) AS [MAX DATE]
	, COUNT(*) AS [ROWS IN PARTITION]
FROM DBO.POST_TRAN_TAB -- PARTITIONED TABLE
GROUP BY $PARTITION.POSTTRANPARTFUNC(DATETIME_TRAN_LOCAL)
ORDER BY [PARTITION NUMBER]
GO

Gbr. 1 Output Listing 3

Gambar 1 menunjukkan kepada kita output dari kueri di Listing 3. Partisi tertua adalah Partisi 2 yang berisi baris dari tahun 2017. Kami memverifikasi ini dengan kueri di Listing 4. Listing 4 juga menunjukkan kepada kita Filegroup mana yang menyimpan data di Partisi 2.

-- Listing 4: Check Filegroup Associated with Partition --

USE POST_OFFICE_HISTORY
GO
SELECT PS.NAME AS PSNAME, 
		DDS.DESTINATION_ID AS PARTITIONNUMBER, 
		FG.NAME AS FILEGROUPNAME
FROM (((SYS.TABLES AS T 
	INNER JOIN SYS.INDEXES AS I 
		ON (T.OBJECT_ID = I.OBJECT_ID))
	INNER JOIN SYS.PARTITION_SCHEMES AS PS 
		ON (I.DATA_SPACE_ID = PS.DATA_SPACE_ID))
	INNER JOIN SYS.DESTINATION_DATA_SPACES AS DDS 
		ON (PS.DATA_SPACE_ID = DDS.PARTITION_SCHEME_ID))
	INNER JOIN SYS.FILEGROUPS AS FG
		ON DDS.DATA_SPACE_ID = FG.DATA_SPACE_ID
WHERE (T.NAME = 'POST_TRAN_TAB') AND (I.INDEX_ID IN (0,1))
	AND DDS.DESTINATION_ID = $PARTITION.POSTTRANPARTFUNC('20171108') ;

Gbr. 1 Output Listing 3

Gambar 2 Output Listing 4

Daftar 4 menunjukkan kepada kita bahwa filegroup yang terkait dengan Partisi 2 adalah NOV . Untuk mematikan Partisi 2, kita memerlukan tabel histori yang merupakan replika dari tabel langsung tetapi berada di grup file yang sama dengan partisi yang ingin kita alihkan. Karena kita sudah memiliki tabel ini, yang kita butuhkan hanyalah membuatnya kembali di Filegroup yang diinginkan. Anda juga perlu membuat ulang indeks berkerumun. Perhatikan bahwa indeks berkerumun ini memiliki definisi yang sama dengan indeks berkerumun pada tabel post_tran_tab dan juga berada di grup file yang sama dengan post_tran_tab_hist tabel.

-- Listing 5: Re-create the History Table 
-- Re-create the History Table --

USE [post_office_history]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

DROP TABLE [dbo].[post_tran_tab_hist]
GO

CREATE TABLE [dbo].[post_tran_tab_hist](
	[tran_nr] [bigint] NOT NULL,
	[tran_type] [char](2) NULL,
	[tran_reversed] [char](2) NULL,
	[batch_nr] [int] NULL,
	[message_type] [char](4) NULL,
	[source_node_name] [varchar](12) NULL,
	[system_trace_audit_nr] [char](6) NULL,
	[settle_currency_code] [char](3) NULL,
	[sink_node_name] [varchar](30) NULL,
	[sink_node_currency_code] [char](3) NULL,
	[to_account_id] [varchar](30) NULL,
	[pan] [varchar](19) NOT NULL,
	[pan_encrypted] [char](18) NULL,
	[pan_reference] [char](70) NULL,
	[datetime_tran_local] [datetime] NOT NULL,
	[tran_amount_req] [float] NOT NULL,
	[tran_amount_rsp] [float] NOT NULL,
	[tran_cash_req] [float] NOT NULL,
	[tran_cash_rsp] [float] NOT NULL,
	[datetime_tran_gmt] [char](10) NULL,
	[merchant_type] [char](4) NULL,
	[pos_entry_mode] [char](3) NULL,
	[pos_condition_code] [char](2) NULL,
	[acquiring_inst_id_code] [varchar](11) NULL,
	[retrieval_reference_nr] [char](12) NULL,
	[auth_id_rsp] [char](6) NULL,
	[rsp_code_rsp] [char](2) NULL,
	[service_restriction_code] [char](3) NULL,
	[terminal_id] [char](8) NULL,
	[terminal_owner] [varchar](25) NULL,
	[card_acceptor_id_code] [char](15) NULL,
	[card_acceptor_name_loc] [char](40) NULL,
	[from_account_id] [varchar](28) NULL,
	[auth_reason] [char](1) NULL,
	[auth_type] [char](1) NULL,
	[message_reason_code] [char](4) NULL,
	[datetime_req] [datetime] NULL,
	[datetime_rsp] [datetime] NULL,
	[from_account_type] [char](2) NULL,
	[to_account_type] [char](2) NULL,
	[insert_date] [datetime] NOT NULL,
	[tran_postilion_originated] [int] NOT NULL,
	[card_product] [varchar](20) NULL,
	[card_seq_nr] [char](3) NULL,
	[expiry_date] [char](4) NULL,
	[srcnode_cash_approved] [float] NOT NULL,
	[tran_completed] [char](2) NULL
) ON [NOV] 

GO

SET ANSI_PADDING OFF
GO

-- Re-create the Clustered Index --
USE [post_office_history]
GO

CREATE CLUSTERED INDEX [IX_Datetime_Local] ON [dbo].[post_tran_tab_hist] 
(
	[datetime_tran_local] ASC,
	[tran_nr] ASC
	
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [NOV]
GO

Mengganti partisi terakhir sekarang menjadi perintah satu baris. Menghitung kedua tabel sebelum dan sesudah menjalankan perintah satu baris ini akan memberikan jaminan bahwa kita memiliki semua data yang diinginkan.

Gbr. 3 Tabel post_tran_tab_hist berada di NOV Filegroup

-- Listing 6: Switching Out the Last Partition
SELECT COUNT(*) FROM 'POST_TRAN_TAB';
SELECT COUNT(*) FROM 'POST_TRAN_TAB_HIST';

USE [POST_OFFICE_HISTORY]
GO
ALTER TABLE POST_TRAN_TAB SWITCH PARTITION 2 TO POST_TRAN_TAB_HIST
GO

SELECT COUNT(*) FROM 'POST_TRAN_TAB';
SELECT COUNT(*) FROM 'POST_TRAN_TAB_HIST';

Karena kami telah mengganti partisi terakhir, kami tidak lagi membutuhkan batas. Kami menggabungkan dua rentang yang sebelumnya dipisahkan oleh batas itu menggunakan perintah di Listing 7. Kami selanjutnya memotong tabel histori seperti yang ditunjukkan pada Listing 8. Kami melakukan ini karena inilah intinya:menghapus data lama yang tidak lagi kami perlukan.

-- Listing 7: Merging Partition Ranges
-- Merge Range

USE [POST_OFFICE_HISTORY]
GO
ALTER PARTITION FUNCTION POSTTRANPARTFUNC() MERGE RANGE ('20171101');


-- Confirm Range Is Merged

USE [POST_OFFICE_HISTORY]
GO
SELECT * FROM SYS.PARTITION_RANGE_VALUES
GO
>

Gambar 4 Batas Digabung

-- Listing 8: Truncate the History Table


USE [post_office_history]
GO
TRUNCATE TABLE post_tran_tab_hist;
GO

Gbr. 5 Jumlah Baris untuk Kedua Tabel sebelum Dipotong

Perhatikan bahwa jumlah baris dalam tabel riwayat sama persis dengan jumlah baris sebelumnya di Partisi 2 seperti yang ditunjukkan pada Gambar 1. Anda juga dapat bekerja ekstra dengan memulihkan ruang kosong di grup file milik yang terakhir partisi. Ini akan berguna jika karena Anda membutuhkan ruang ini untuk data baru yang akan berada di partisi sebelumnya. Langkah ini mungkin tidak diperlukan jika Anda merasa memiliki cukup ruang di lingkungan Anda.

-- Listing 9: Recover Space on Operating System
-- Determine that File has been emptied

USE [post_office_history]
GO
SELECT DF.FILE_ID, DF.NAME, DF.PHYSICAL_NAME, DS.NAME, DS.TYPE, DF.STATE_DESC FROM SYS.DATABASE_FILES DF
JOIN SYS.DATA_SPACES DS ON DF.DATA_SPACE_ID = DS.DATA_SPACE_ID;

Gambar 7 Pemetaan File ke Filegroup

-- Shrink the file to 2GB

USE [post_office_history]
GO
DBCC SHRINKFILE (N'post_office_history_part_11’, 2048)
GO


-- From the OS confirm free space on disks

SELECT DISTINCT DB_NAME (S.DATABASE_ID) AS DATABASE_NAME,
S.DATABASE_ID, S.VOLUME_MOUNT_POINT
--, S.VOLUME_ID
, S.LOGICAL_VOLUME_NAME
, S.FILE_SYSTEM_TYPE
, S.TOTAL_BYTES/1024/1024/1024 AS [TOTAL_SIZE (GB)]
, S.AVAILABLE_BYTES/1024/1024/1024 AS [FREE_SPACE (GB)]
, LEFT ((ROUND (((S.AVAILABLE_BYTES*1.0)/S.TOTAL_BYTES), 4)*100),4) AS PERCENT_FREE
FROM SYS.MASTER_FILES AS F
CROSS APPLY SYS.DM_OS_VOLUME_STATS (F.DATABASE_ID, F.FILE_ID) AS S
WHERE DB_NAME (S.DATABASE_ID) = 'POST_OFFICE_HISTORY';

Gbr. 8 Ruang Kosong pada Sistem Operasi

Kesimpulan

Pada artikel ini, kami telah melakukan penelusuran proses untuk mengganti partisi dari tabel yang dipartisi. Ini adalah cara yang sangat efisien untuk mengelola pertumbuhan data secara native di SQL Server. Teknologi yang lebih canggih seperti Stretch Database tersedia dalam versi SQL Server saat ini.

Referensi

Isakov, V. (2018). Ref Ujian 70-764 Mengelola Infrastruktur Database SQL. Pendidikan Pearson

Tabel dan Indeks yang Dipartisi di SQL Server


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server UNTUK XML Path membuat node berulang

  2. Mengembalikan Daftar Tabel &Tampilan di SQL Server menggunakan T-SQL (sp_tables)

  3. Tambahkan batasan unik ke kombinasi dua kolom

  4. Pernyataan SQL UPDATE untuk mengganti dua nilai dalam dua baris

  5. Dapatkan Bagian Kiri dari String di SQL Server (T-SQL)