小编McN*_*ets的帖子

默认约束,值得吗?

我通常按​​照以下规则设计我的数据库:

  • 除了 db_owner 和 sysadmin 之外,没有其他人可以访问数据库表。
  • 用户角色在应用层控制。我通常使用一个 db 角色来授予对视图、存储过程和函数的访问权限,但在某些情况下,我添加了第二条规则来保护一些存储过程。
  • 我使用 TRIGGERS 来初步验证关键信息。

CREATE TRIGGER <TriggerName>
ON <MyTable>
[BEFORE | AFTER] INSERT
AS
    IF EXISTS (SELECT 1 
               FROM   inserted
               WHERE  Field1 <> <some_initial_value>
               OR     Field2 <> <other_initial_value>)
    BEGIN
        UPDATE MyTable
        SET    Field1 = <some_initial_value>,  
               Field2 = <other_initial_value>  
        ...  
    END
Run Code Online (Sandbox Code Playgroud)
  • DML 使用存储过程执行:

sp_MyTable_Insert(@Field1, @Field2, @Field3, ...);
sp_MyTable_Delete(@Key1, @Key2, ...);
sp_MyTable_Update(@Key1, @Key2, @Field3, ...);
Run Code Online (Sandbox Code Playgroud)

您认为,在这种情况下,使用 DEFAULT CONSTRAINT 是否值得,或者我正在向数据库服务器添加额外且不必要的工作?

更新

我知道通过使用 DEFAULT 约束,我向必须管理数据库的其他人提供了更多信息。但我最感兴趣的是性能。

我假设数据库总是检查默认值,即使我提供了正确的值,因此我做了两次相同的工作。

例如,有没有办法在触发器执行中避免 DEFAULT 约束?

performance database-design sql-server t-sql default-value query-performance

20
推荐指数
2
解决办法
4415
查看次数

为什么子查询中的 COALESCE 返回 NULL?

鉴于此架构:

CREATE TABLE #TEST_COALESCE
(
    Id int NOT NULL,
    DateTest datetime NOT NULL,
    PRIMARY KEY (Id, DateTest)
);

INSERT INTO #TEST_COALESCE VALUES
(1, '20170201'),
(1, '20170202'),
(1, '20170203'),
(2, '20170204'),
(2, '20170205'),
(2, '20170206');
Run Code Online (Sandbox Code Playgroud)

如果我在子查询中使用 COALESCE,它将返回 NULL。

SELECT  t1.Id, t1.DateTest,
        (SELECT TOP 1 COALESCE(t2.DateTest, t1.DateTest)
         FROM         #TEST_COALESCE t2
         WHERE        t2.Id = t1.Id
         AND          t2.DateTest > t1.DateTest
         ORDER BY     t2.Id, t2.DateTest) NextDate
FROM    #TEST_COALESCE t1;

+----+---------------------+---------------------+
| Id | DateTest            | NextDate            |
+----+---------------------+---------------------+
| 1  | 01.02.2017 00:00:00 | 02.02.2017 …
Run Code Online (Sandbox Code Playgroud)

sql-server

15
推荐指数
1
解决办法
5233
查看次数

MS-SQL 上是否有任何(隐藏的)内置函数来取消引用对象名称?

有时我将对象名称(标识符)存储在我们的一些数据库中,例如在一些参数表中。因为我使用 '=' 或 'LIKE' 比较运算符从这些表中选择记录,所以我必须注意存储这些名称时总是带括号或不带括号

IF EXISTS (SELECT 1 FROM MYTABLE WHERE OBJ_NAME = '[TABLE_NAME]';
Run Code Online (Sandbox Code Playgroud)

或者

IF EXISTS (SELECT 1 FROM MYTABLE WHERE OBJ_NAME = 'TABLE_NAME';
Run Code Online (Sandbox Code Playgroud)

但是,MS-SQL 有一些函数,您可以在其中使用带或不带括号的对象名称,例如 OBJECT_ID() 函数。我在dbfiddle.uk上设置了一个最小的例子。

CREATE TABLE TEST
(
    ID     INT IDENTITY(1,1) PRIMARY KEY,
    OBJECT sysname NOT NULL
);
GO

INSERT INTO TEST VALUES ('[obj1]'),('obj2'),('obj3'),('[obj4]');
GO
Run Code Online (Sandbox Code Playgroud)

现在我可以使用 OBJECT_ID() 以这种方式检查表 TEST 是否存在:

IF OBJECT_ID('TEST') IS NOT NULL
BEGIN
    SELECT 'TEST EXISTS.' OBJECT_ID;
END
GO

| OBJECT_ID    |
| :----------- | …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

12
推荐指数
3
解决办法
2351
查看次数

为什么优化器会选择聚集索引 + 排序而不是非聚集索引?

给出下一个例子:

IF OBJECT_ID('dbo.my_table') IS NOT NULL
    DROP TABLE [dbo].[my_table];
GO

CREATE TABLE [dbo].[my_table]
(
    [id]    int IDENTITY (1,1)  NOT NULL PRIMARY KEY,
    [foo]   int                 NULL,
    [bar]   int                 NULL,
    [nki]   int                 NOT NULL
);
GO

/* Insert some random data */
INSERT INTO [dbo].[my_table] (foo, bar, nki)
SELECT TOP (100000)
    ABS(CHECKSUM(NewId())) % 14,
    ABS(CHECKSUM(NewId())) % 20,
    n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
FROM 
    sys.all_objects AS s1 
CROSS JOIN 
    sys.all_objects AS s2
GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_my_table]
    ON [dbo].[my_table] …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2012 nonclustered-index

11
推荐指数
2
解决办法
658
查看次数

为什么不应该使用 INFORMATION_SCHEMA 视图来确定对象的架构?

根据 MS-DOCS about System information schema views,架构列定义有一个警告说明:

**重要** 不要使用 INFORMATION_SCHEMA 视图来确定对象的架构。查找对象架构的唯一可靠方法是查询 sys.objects 目录视图。

为什么不能使用 INFORMATION_SCHEMA 视图来确定对象的架构?

这个信息有误吗?

schema sql-server metadata information-schema sql-server-2017

10
推荐指数
1
解决办法
311
查看次数

我可以从自引用(分层)表中获取树结构吗?

给定一个这样的分层表:

CREATE TABLE [dbo].[btree]
(
  id INT PRIMARY KEY
, parent_id INT REFERENCES [dbo].[btree] ([id])
, name NVARCHAR(20)
);
Run Code Online (Sandbox Code Playgroud)

我想获得整个树结构。

例如,使用此数据:

INSERT INTO [btree] VALUES (1, null, '1 Root');
INSERT INTO [btree] VALUES (2,    1, '1.1 Group');
INSERT INTO [btree] VALUES (3,    1, '1.2 Group');
INSERT INTO [btree] VALUES (4,    2, '1.1.1 Group');
INSERT INTO [btree] VALUES (5,    2, '1.1.2 Group');
INSERT INTO [btree] VALUES (6,    3, '1.2.1 Group');
INSERT INTO [btree] VALUES (7,    3, '1.2.2 Group');
INSERT INTO [btree] …
Run Code Online (Sandbox Code Playgroud)

hierarchy t-sql sql-server-2014

9
推荐指数
1
解决办法
2万
查看次数

仅当子表中的所有记录都具有值时,单个 sql 查询才能从父表中选择一条记录

我有 Table1 和 Table2,Table1 的 PK 是 Table2 的 FK。现在,当且仅当与 Table1 记录对应的 Table2 中的所有记录都有值时(如果任何字段值为空,则跳过),我需要从 Table1 中执行选择

即,对于表 1 中的 id,表 2 中有多个子 id。在这些多个 id 中,如果某个特定字段对应于任何一个 id 为空,则应该跳过 select。

任何人请帮我为这个要求写一个 sql 查询。

sql-server

8
推荐指数
1
解决办法
10万
查看次数

我的磁盘充满了 binlog 文件

我刚刚意识到我的服务器每天增长 2 GB,这不正常。

我查看了我的文件夹,文件夹 /var/lib/mysql 达到了 26 GB

一般情况下应该是4GB左右

一个月前,我将 MySQL 5.7 数据库迁移到 MySQL 8.0

我认为我的磁盘充满了 binlog 文件。

我想知道为什么这些文件突然变大了?

如何在不损坏数据库的情况下修复此问题?

total 26511376
-rw-r----- 1 mysql mysql         56 Aug 19  2018  auto.cnf
-rw-r----- 1 mysql mysql        178 Mar 10 06:07  binlog.000001
-rw-r----- 1 mysql mysql   73883481 Mar 10 06:25  binlog.000002
-rw-r----- 1 mysql mysql   58601919 Mar 10 13:13  binlog.000003
-rw-r----- 1 mysql mysql  178322334 Mar 11 06:25  binlog.000004
-rw-r----- 1 mysql mysql  379019579 Mar 12 06:25  binlog.000005
-rw-r----- 1 mysql mysql …
Run Code Online (Sandbox Code Playgroud)

mysql ubuntu log mysql-8.0

8
推荐指数
2
解决办法
2万
查看次数

选择对 (a,b) 排除 (b,a) 具有相同的值

对于这样的给定结构:

+----+----------+
| ID |   Name   |
+----+----------+
| a  | ZZZZZZZZ |
| b  | YYYYYYYY |
| c  | WWWWWWWW |
| d  | ZZZZZZZZ |
| e  | YYYYYYYY |
| f  | WWWWWWWW |
+----+----------+
Run Code Online (Sandbox Code Playgroud)

获取具有相同名称的对 (ID, ID2) 的列表,排除 (ID2, ID) 具有对应 (ID, ID2) 的所有记录。

+----+----------+-----+
| ID |   Name   | ID2 |
+----+----------+-----+
| a  | ZZZZZZZZ |  d  |
| b  | YYYYYYYY |  e  |
| c  | WWWWWWWW |  f  |
+----+----------+-----+ …
Run Code Online (Sandbox Code Playgroud)

sql-server

7
推荐指数
1
解决办法
2万
查看次数

从某个日期范围内的价目表更新未结订单

设置

我已经在reextesterdbfiddle上设置了一个示例。

设想

Price list : 它是产品价格表,一个产品可以有多个活动价格,甚至是未来价格。

+---------+-------+------------+--------+--------+
| product | price | date_price |  base  | active |
+---------+-------+------------+--------+--------+
|   0125  |    90 | 01.01.2017 |  1200  |    0   |
|   0125  |   100 | 25.01.2017 |  1000  |    1   |
|   0125  |   110 | 27.02.2017 |   500  |    1   |
+---------+-------+------------+--------+--------+
|   1200  |   140 | 01.01.2017 |  2000  |    0   |
|   1200  |   150 | 01.02.2017 |  1500  |    1   | …
Run Code Online (Sandbox Code Playgroud)

sql-server-2005 sql-server

7
推荐指数
1
解决办法
164
查看次数