最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SqlServer 垂直分表(減少程序改動)

 更新時間:2021年04月15日 13:03:19   作者:薛定諤的DBA  
當(dāng)單表數(shù)據(jù)太多時,我們可以水平劃分,參考 SqlServer 分區(qū)視圖實現(xiàn)水平分表 ,水平劃分可以提高表的一些性能

由于sqlserver的設(shè)計特殊性,一般大量數(shù)據(jù)一般都是采用水平分表,而垂直分表只是把text、圖片都較大數(shù)據(jù)放到單獨的表中,這樣數(shù)據(jù)設(shè)計會更合理,相對于mysql可能要好一點,mssql本來就是一個文件,基本上提升不大,目前來看幾十萬的數(shù)據(jù)沒有分不分表沒有任何影響,對于千萬以上數(shù)據(jù)還是采用水平分表比較好。

而 垂直分表 則相對很少見到和用到,因為這可能是數(shù)據(jù)庫設(shè)計上的問題了。如果數(shù)據(jù)庫中一張表有部分字段幾乎從不不更改但經(jīng)常查詢,而部分字段的數(shù)據(jù)頻繁更改,這種設(shè)計放到同一個表中就不合理了,相互影響太大了。在已存在改情況的表的時候,可以考慮按列拆分表,即垂直拆分。

由于垂直分表的案例比較少,最近因為存在這樣的表,所以個人搗鼓了一下。

源表設(shè)計結(jié)構(gòu):

--  源表
CREATE TABLE [dbo].[DemoTab](
[Guid] [uniqueidentifier] NOT NULL,
[UserName] [nvarchar](30) NOT NULL,
[Password] [nvarchar](30) NOT NULL,
[UserAccount] [varchar](30) NOT NULL,
[Amount] [numeric](18, 4) NULL,
CONSTRAINT [PK_DemoTab] PRIMARY KEY CLUSTERED ([Guid])
)
GO
 
 
ALTER TABLE [dbo].[DemoTab] 
ADD CONSTRAINT [DF_DemoTab_Guid] DEFAULT (newsequentialid()) FOR [Guid]
GO
 
--  原來是訪問視圖的(好處就是視圖層不變)
CREATE VIEW [dbo].[VDemoTab]
AS
SELECT [Guid],[UserName],[Password],[UserAccount],[Amount]
FROM [dbo].[DemoTab]
GO

注:拆分后各表的主鍵都是相同了,而且拆分后的表是規(guī)范化的。

現(xiàn)在拆成兩張表:

注意選擇一張表作為基表,其他表都有與該表的外鍵。

--  分表【1】,以該表為"主表",其他拆分出的表為"子表"
CREATE TABLE [dbo].[DemoTab001](
[Guid] [uniqueidentifier] NOT NULL,
[UserName] [nvarchar](30) NOT NULL,
[Password] [nvarchar](30) NOT NULL,
CONSTRAINT [PK_DemoTab001] PRIMARY KEY CLUSTERED ([Guid])
)
GO
 
--  主鍵默認(rèn)值可以不需要,因為插入數(shù)據(jù)前需要確定主鍵值
--ALTER TABLE [dbo].[DemoTab001] 
--ADD CONSTRAINT [DF_DemoTab001_Guid] DEFAULT (newsequentialid()) FOR [Guid]
--GO
 
--  分表【2】,"子表"
CREATE TABLE [dbo].[DemoTab002](
[Guid] [uniqueidentifier] NOT NULL,
[UserAccount] [varchar](30) NOT NULL,
[Amount] [numeric](18, 4) NULL,
CONSTRAINT [PK_DemoTab002] PRIMARY KEY CLUSTERED ([Guid])
)
GO
 
--  主鍵默認(rèn)值可以不需要,因為插入數(shù)據(jù)前需要確定主鍵值
--ALTER TABLE [dbo].[DemoTab002] 
--ADD CONSTRAINT [DF_DemoTab002_Guid] DEFAULT (newsequentialid()) FOR [Guid]
--GO
 
 
--  若主表變更主鍵則級聯(lián)更新或刪除(主鍵通常是不更新的,也可省去 ON UPDATE CASCADE)
ALTER TABLE [dbo].[DemoTab002] 
ADD CONSTRAINT [FK_DemoTab002_DemoTab001_Guid] FOREIGN KEY ([Guid]) 
REFERENCES [DemoTab001]([Guid]) ON UPDATE CASCADE ON DELETE CASCADE
GO

如果之前是對單個表或者視圖操作,拆分之后邏輯層改動可能很多,為保持改動最小,可以用聯(lián)合視圖操作。怎么連接表依個人情況而定。

--  拆分后使用聯(lián)合視圖(INNER JOIN 也可以)
ALTER VIEW [dbo].[VDemoTab]
AS
SELECT T1.[Guid],T1.[UserName],T1.[Password],T2.[UserAccount],T2.[Amount]
FROM [dbo].[DemoTab001] T1 LEFT JOIN [dbo].[DemoTab002] T2 ON T1.[Guid]=T2.[Guid]
GO

這時問題來了,要對表進(jìn)行DML操作,insert , update , delete 怎么解決?因為要求主鍵是分散在多個表并且是相同的!

這時只能用考慮觸發(fā)器來保證一致性了,觸發(fā)器則定義在視圖上,使用的是 INSTEAD OF 類型的觸發(fā)器。

insert 觸發(fā)器:

視圖 [VDemoTab] 中的 [Guid] 為表 插入時值,在插入觸發(fā)器中,虛擬表[inserted]的[Guid]是唯一的,所以在觸發(fā)器中可以同時使用該 [Guid] 插入到多個分表中,保證了多個分表的[Guid]是相同的!

--  insert 觸發(fā)器
CREATE TRIGGER [dbo].[tgr_VDemoTab_insert]
ON [dbo].[VDemoTab] 
INSTEAD OF INSERT
AS 
BEGIN
 INSERT INTO [dbo].[DemoTab001]([Guid],[UserName],[Password])
 SELECT [Guid],[UserName],[Password] FROM inserted;
 
 INSERT INTO [dbo].[DemoTab002]([Guid],[UserAccount],[Amount])
 SELECT [Guid],[UserAccount],[Amount] FROM inserted;
END
GO

update 觸發(fā)器:

同理,更新時涉及虛擬表 deleted 和 inserted,而更新是對視圖[VDemoTab]更新的,所以虛擬表inserted包括了所有的字段,所以需要觸發(fā)器分別更新多個分表。

--  update 觸發(fā)器
CREATE TRIGGER [dbo].[tgr_VDemoTab_update]  
ON [dbo].[VDemoTab]   
INSTEAD OF UPDATE  
AS
BEGIN
 UPDATE T1 SET 
 T1.[UserName] = T2.[UserName], 
 T1.[Password] = T2.[Password]
 FROM [dbo].[DemoTab001] AS T1, inserted AS T2 WHERE T1.[Guid] = T2.[Guid] 
 
 UPDATE T1 SET 
 T1.[UserAccount] = T2.[UserAccount], 
 T1.[Amount] = T2.[Amount]
 FROM [dbo].[DemoTab002] AS T1, inserted AS T2 WHERE T1.[Guid] = T2.[Guid] 
END
GO

delete 觸發(fā)器:

刪除視圖[VDemoTab]記錄,涉及多個表則不允許刪除,因此只要刪除"主表"的記錄即可,其他分表都會級聯(lián)刪除。

--  delete 觸發(fā)器
CREATE TRIGGER [dbo].[tgr_VDemoTab_delete]  
ON [dbo].[VDemoTab]   
INSTEAD OF DELETE  
AS
BEGIN
    DELETE FROM [dbo].[DemoTab001]
    WHERE [Guid] IN (SELECT [Guid] FROM deleted)
END
GO

設(shè)計基本就完成了,現(xiàn)在進(jìn)行測試。

INSERT INTO [dbo].[VDemoTab]([Guid],[UserName],[Password],[UserAccount],[Amount])
SELECT NEWID(),'user01','pw01','account01',100
UNION ALL
SELECT NEWID(),'user02','pw02','account02',99
UNION ALL
SELECT NEWID(),'user03','pw03','account03',0
GO
 
UPDATE [VDemoTab] SET [Password]='pw',[Amount]='10'
WHERE [Amount] >=0 AND [Amount]<100 AND [UserName] LIKE '%3'
GO
 
DELETE FROM [VDemoTab] WHERE [UserName] = 'user03'
GO
 
SELECT * FROM [dbo].[DemoTab001] 
SELECT * FROM [dbo].[DemoTab002] 
SELECT * FROM [dbo].[VDemoTab]

基本操作都是正常的!垂直分表完成!

性能怎么樣呢?

由于 Guid 作為主鍵,使用的是 NEWID() 而不是  NEWSEQUENTIALID(),新增記錄時聚集索引都可能重新排序較多數(shù)據(jù)。

分表之后,單個數(shù)據(jù)頁能存儲的數(shù)據(jù)更多了,但是分成多個表中,數(shù)據(jù)頁也增多了,同時 Guid 在每個表都存在,所以查詢數(shù)據(jù)時IO會更多。

對于更新數(shù)據(jù),在觸發(fā)器中是兩個表同時更新的,即使更新其中一個分表,其他分表都會影響。如果分表之后不同時更新,可以在觸發(fā)器中使用 if(update(col)) 來判斷更新的是那一列,就更新相應(yīng)的基表就行,其他分表不更新。

最好的情況就是,拆分后的表都是“獨立”的,不用聯(lián)合視圖,查詢和更改都獨立,這需要更改邏輯層。

到此這篇關(guān)于SqlServer 垂直分表(減少程序改動)的文章就介紹到這了,更多相關(guān)SqlServer 垂直分表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文掌握SQL的 joins 語法

    一文掌握SQL的 joins 語法

    SQL JOIN是結(jié)合兩個或多個表的數(shù)據(jù)的一種方式,INNER JOIN返回兩表匹配的記錄;LEFT JOIN返回左表所有記錄及右表匹配記錄;RIGHT JOIN返回右表所有記錄及左表匹配記錄;FULL JOIN返回兩表中所有記錄,無論是否匹配,這些JOIN類型有助于靈活查詢和分析關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)
    2024-09-09
  • 淺析SQL Server中包含事務(wù)的存儲過程

    淺析SQL Server中包含事務(wù)的存儲過程

    數(shù)據(jù)庫事務(wù)(Database Transaction) ,是指作為單個邏輯工作單元執(zhí)行的一系列操作,要么完整地執(zhí)行,要么完全地不執(zhí)行。那么在存儲過程里添加事務(wù),則可以保證該事務(wù)里的所有sql代碼要么完全執(zhí)行要么完全不執(zhí)行。
    2014-08-08
  • master數(shù)據(jù)庫損壞的解決辦法有哪些

    master數(shù)據(jù)庫損壞的解決辦法有哪些

    由于sqlserver 2008 master數(shù)據(jù)庫損壞導(dǎo)致sqlserver服務(wù)啟動失敗,本文給大家master數(shù)據(jù)庫損壞的解決辦法,感興趣的朋友一起參考下
    2015-10-10
  • SQL Server正確刪除Windows認(rèn)證用戶的方法

    SQL Server正確刪除Windows認(rèn)證用戶的方法

    這篇文章主要給大家介紹了關(guān)于SQL Server正確刪除Windows認(rèn)證用戶的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用SQL Server具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 基于SQL Server中如何比較兩個表的各組數(shù)據(jù) 圖解說明

    基于SQL Server中如何比較兩個表的各組數(shù)據(jù) 圖解說明

    本篇文章小編為大家介紹,基于SQL Server中如何比較兩個表的各組數(shù)據(jù) 圖解說明。需要的朋友參考下
    2013-04-04
  • Navicat連接本地SqlServer出現(xiàn)?[08001][Microsoft][sQL?Server?Native?Client?11.0]的解決方法

    Navicat連接本地SqlServer出現(xiàn)?[08001][Microsoft][sQL?Server?Nati

    這篇文章主要給大家介紹了Navicat連接本地SqlServer出現(xiàn)?[08001][Microsoft][sQL?Server?Native?Client?11.0]命名管道提供程序:無法打開與SQL?Server等錯誤的解決方法,需要的朋友可以參考下
    2023-09-09
  • 實例學(xué)習(xí)mssql存儲過程分析

    實例學(xué)習(xí)mssql存儲過程分析

    以下我來具體舉三個例子說明存儲過程的3個主要用法吧:
    2008-07-07
  • 關(guān)于SQL數(shù)據(jù)庫 msdb.dbo.sp_send_dbmail 函數(shù)發(fā)送郵件的場景分析

    關(guān)于SQL數(shù)據(jù)庫 msdb.dbo.sp_send_dbmail 函數(shù)發(fā)送郵件的場景分析

    這篇文章主要介紹了關(guān)于SQL數(shù)據(jù)庫 msdb.dbo.sp_send_dbmail 函數(shù)發(fā)送郵件的場景分析,需要的朋友可以參考下
    2018-10-10
  • SQL Server中搜索特定的對象

    SQL Server中搜索特定的對象

    這篇文章介紹了SQL Server搜索特定對象的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • SQL Server 2012 FileTable 新特性詳解

    SQL Server 2012 FileTable 新特性詳解

    FileTable是基于FILESTREAM的一個特性。本文給大家介紹SQL Server 2012 FileTable 新特性詳解,非常不錯,感興趣的朋友一起學(xué)習(xí)吧
    2016-08-08

最新評論

阜康市| 兰溪市| 百色市| 南阳市| 甘谷县| 唐山市| 徐州市| 南阳市| 蛟河市| 牙克石市| 贵南县| 昌吉市| 永登县| 合川市| 常德市| 重庆市| 祁阳县| 桐柏县| 双江| 镇坪县| 灵山县| 古丈县| 二连浩特市| 汉寿县| 长丰县| 大兴区| 大渡口区| 昌乐县| 黎城县| 志丹县| 外汇| 姚安县| 万载县| 江达县| 东山县| 平武县| 长治市| 咸丰县| 通渭县| 平湖市| 扬州市|