Microsoft SQL Server分布式数据库

    技术2022-05-20  39

    本实现以Microsoft SQL Server 为例.

    分布式数据库系统:在逻辑上是一个整体,在物理上数据存储在不通的物理节点上.

    因为各实例在逻辑上是一个整体,所以各节点要能互相访问(通过通信网络实现逻辑上的一个整体),

    在数据库系统内部,各实例通过链接服务器进行通信交互

    链接服务器:

    链接服务器可以访问远程服务器(包括异类数据源),依此实现分布式的命令和事务.

    通过sp_addlinkedserver创建链接服务器

    通过sp_addlinkedsrvlogin创建本地SQL Server实例上的登录与链接服务器上远程登录之间的映射

    通过sp_dropserver删除链接服务器

    通过sp_droplinkedsrvlogin删除本地SQL Server实例上的登录与链接服务器上远程登录之间的映射

    在删除链接服务器时先删除相关的登录映射再删除链接服务器

     

    以下命令是在本地实例上创建名为remoteLink的链接服务器,远程数据库服务器的IP为192.168.72.128

    exec sp_addlinkedserver 

    @server='remoteLink'

    ,@provider='SQLNCLI'

    ,@srvproduct=''

    ,@datasrc='192.168.72.128'

    以下命令为remoteLink链接服务器创建远程登录映射

    exec sp_addlinkedsrvlogin 

    @rmtsrvname = 'remoteLink'

    ,@useself = 'false'

    , @locallogin = null

    , @rmtuser = 'sa'

    , @rmtpassword = '123456'

    以下命令删除链接服务器remoteLink对应的SA账号登录映射

    sp_droplinkedsrvlogin 'remoteLink','sa'

    以下命令删除链接服务器remoteLink(在删除链接服务器前需要将链接服务器对应的登录映射全部删除)

    sp_dropserver 'remoteLink'

    分布式查询:

    在本地实例上引用对远程实例上的对象,必须使用全名称引用:连接服务器.数据库.所有者.对象

    以下命令查询链接服务器remoteLink上的DistributedTest数据库里的test表的数据

    select * from remoteLink.DistributedTest.dbo.test

    可以通过create synonym为连接服务器创建别名

    以下命令为链接服务器器remoteLink上的DistributedTest数据库里的test表创建别名remoteLinkTest

    create synonym remoteLinkTest for remoteLink.DistributedTest.dbo.test

    通过别名完成上面的查询:select * from remoteLinkTest

    以下命令删除别名:

    drop synonym remoteLinkTest

    分布式事务:

    分布式事务需要操作系统的MSDTC组件的支持.

    一下是相关配置步骤:

    1.启动Distributed Transaction Coordinator服务

    2.配置DTC安全设置:打开"管理工具"-->"组件服务"-->"计算机",在"我的电脑"上点击右键在"MSDTC选项卡"中,点击"安全配置"按钮

    3.选中"网络DTC访问"

    在"客户端管理"中选中"允许远程客户端","允许远程管理"

    在"事务管理通讯"中选中"允许入站","允许出站","不要求进行验证"

    选中"启用 XA 事务"

    4.确保DTC登录账户为:NT AUTHORITY/NetworkService

    5.确保135端口启用(注意防火墙的设置)

    6.设置好后重启电脑

    注意:相关机器一定要能互相访问

    以下命令完成一次分布式事务操作:

    set xact_abort on

    begin distributed transaction

    begin try

    update remotelink.distributedtest.dbo.test set code=0

    commit transaction

    end try

    begin catch

    rollback transaction

    select ERROR_MESSAGE()

    end catch

    分布式分区视图:

    分布式分区视图可以将来自一个或多个SQL Server数据库实例中的数据连接起来.使分布在不通实例上的数据形成一个逻辑整体.

    (各成员表通过union all合并数据,如果使用了远程实例,则通过链接服务器引用远程实例)

    分区视图的各成员表必须包含一个CHECK约束列(分区列),CHECK约束列作为主键的一部分,则可以通过分区视图进行更新,否则需要创建

    对应的触发器完成相应的操作.

    注意:分区列必须是表的PRIMARY KEY的一部分,分区列不能是计算列、标识列、默认列或timestamp列.

    以下命令创建分区试图的成员表game_doudizhu:

    create table game_doudizhu

    (

    record_id uniqueidentifier not null,

    game_id nvarchar(10) not null,

    userid int not null,

    writetime datetime not null default(getdate()),

    constraint pk_game_doudizhu primary key clustered(game_id,writetime) with(ignore_dup_key=off),

    constraint ck_game_id check(game_id='doudizhu')

    )

    以下命令创建分区视图:

    create view v_game_record

    as

    (

    select * from game_doudizhu

    union all

    select * from remotelink.distributedtest.dbo.game_majiang

    )

    完整实例:

    --分别在源服务器和远程服务器上创建测试数据库

    create database DistributedTest

    go

     

    --在远程数据库实例上创建一下表:

    use DistributedTest

    go

    create table game_majiang

    (

    record_id uniqueidentifier not null,

    game_id nvarchar(10) not null,

    userid int not null,

    writetime datetime not null default(getdate()),

    constraint pk_game_majiang primary key clustered(game_id,writetime) with(ignore_dup_key=off),

    constraint ck_game_id check(game_id='majiang')

    )

    --在本机数据库实例上创建以下表:

    use DistributedTest

    go

    create table game_doudizhu

    (

    record_id uniqueidentifier not null,

    game_id nvarchar(10) not null,

    userid int not null,

    writetime datetime not null default(getdate()),

    constraint pk_game_doudizhu primary key clustered(game_id,writetime) with(ignore_dup_key=off),

    constraint ck_game_id check(game_id='doudizhu')

    )

    go

    --在本地数据库上创建远程数据库的链接登录对象

    exec sp_addlinkedserver 

    @server='remoteLink'

    ,@provider='SQLNCLI'

    ,@srvproduct=''

    ,@datasrc='192.168.72.128'

    go

    exec sp_addlinkedsrvlogin 

    @rmtsrvname = 'remoteLink'

    ,@useself = 'false'

    , @locallogin = null

    , @rmtuser = 'sa'

    , @rmtpassword = '123456'

    go

    --在源数据库使用链接服务器对象查询远程数据库的数据,如果有结果集返回则说明可以在元数据库对远程数据库进行访问

    select * from remotelink.distributedtest.dbo.game_majiang

    go

    --在本机上创建分区视图:

    create view v_game_record

    as

    (

    select * from game_doudizhu

    union all

    select * from remotelink.distributedtest.dbo.game_majiang

    )

    go

    --通过视图插入数据:

    insert into v_game_record(record_id,game_id,userid,writetime)

    values(NEWID(),'majiang',100,GETDATE())

    insert into v_game_record(record_id,game_id,userid,writetime)

    select NEWID(),'doudizhu',200,GETDATE()

     

    --通过视图查看数据:

    select * from v_game_record

     

    --开启分布式事务插入修改数据:

    set xact_abort on

    begin distributed transaction

    begin try

    insert into v_game_record(record_id,game_id,userid,writetime)

    values(NEWID(),'majiang',300,GETDATE())

    update v_game_record set record_id = newid(),game_id='majiang' where userid= 100

    commit transaction

    end try

    begin catch

    rollback transaction

    select ERROR_MESSAGE()

    end catch

     


    最新回复(0)