如何保证统计表的连续性?

2024-01-07

In ,Joe Celko 提供了 Series 表(其他地方称为 Tally 或 Numbers)的 ANSI SQL 定义。他的定义确保列中的值是唯一的、正数且从 1 到最大值连续:

CREATE TABLE Series (
  seq INTEGER NOT NULL PRIMARY KEY,
  CONSTRAINT non_negative_nbr CHECK (seq > 0),
  CONSTRAINT numbers_are_complete CHECK ((SELECT COUNT(*) FROM Series) = (SELECT MAX(seq) FROM Series))
);

PRIMARY KEY 声明确保唯一性。积极性由约束保证non_negative_nbr。有了这两个约束,约束就保证了连续性numbers_are_complete.

SQL Server 不支持检查约束中的子查询。当我尝试创建系列表时,我收到如下错误:

Msg 1046, Level 15, State 1, Line 4
Subqueries are not allowed in this context. Only scalar expressions are allowed.
Msg 102, Level 15, State 1, Line 4
Incorrect syntax near ')'.

如果我删除不支持的约束numbers_are_complete,我留下这个定义:

CREATE TABLE Series (
  seq INTEGER NOT NULL PRIMARY KEY,
  CONSTRAINT non_negative_nbr CHECK (seq > 0)
);

当我尝试创建此版本的系列时,它成功了:

Command(s) completed successfully.

此版本的 Series 较弱,因为它不强制表中数字的连续性。

为了演示这一点,首先我必须填充表。我采用了 Itzik Ben-Gan 在他的文章中描述的技术“虚拟辅助数字表 http://www.sqlmag.com/article/sql-server/virtual-auxiliary-table-of-numbers' 对 65,536 行有效地执行此操作:

WITH
N0(_) AS (SELECT NULL UNION ALL SELECT NULL),
N1(_) AS (SELECT NULL FROM N0 AS L CROSS JOIN N0 AS R),
N2(_) AS (SELECT NULL FROM N1 AS L CROSS JOIN N1 AS R),
N3(_) AS (SELECT NULL FROM N2 AS L CROSS JOIN N2 AS R),
N4(_) AS (SELECT NULL FROM N3 AS L CROSS JOIN N3 AS R)
INSERT INTO Series (
  seq
)
SELECT
  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM N4;

该查询产生如下输出:

(65536 row(s) affected)

现在我可以从这样的表中进行选择以生成 65,536 行:

SELECT seq
FROM Series;

我已经截断了结果集,但它看起来像这样:

seq
1
2
...
65535
65536

自己检查一下,你会发现区间 [1, 65536] 中的每个数字都在结果集中。该系列是连续的。

但我可以通过删除不是范围端点的任何行来打破连续性:

DELETE FROM Series
WHERE seq = 25788;

如果强制执行连续性,此语句将引发错误,但它会成功:

(1 row(s) affected)

人类很难通过目视检查找到缺失的值。在遇到麻烦之前,他们必须首先怀疑某个值丢失了。由于这些原因,篡改 Series 数据是一种向依赖 Series 表连续的 SQL Server 应用程序引入细微错误的简单方法。

假设用户编写了一个从 Sequence 读取的查询,以枚举来自另一个源的行。经过我的篡改,该查询现在会在某个值附近产生不正确的结果 - 到第 25,788 行时,所有内容都减少了 1。

可以编写一个查询来检测 Series 表中的缺失值,但如何限制该表以使缺失值成为不可能?


我有三个可能的建议:


(1) 将数字表设置为只读(例如拒绝更新/插入/删除)。为什么你要从这个表中删除呢?您的应用程序当然不应该这样做,并且您的用户也不应该能够手动这样做。用户按下“这个按钮有什么作用?”时不需要所有这些检查约束。按钮,此时您可以简单地删除该按钮。

DENY DELETE ON dbo.Serial TO [your_app_user];
-- repeat for individual users/roles

(2) 更简单的是创建一个替代触发器来首先防止删除:

CREATE TRIGGER dbo.LeaveMyNumbersAlone
ON dbo.Serial
INSTEAD OF DELETE
AS
BEGIN
  SET NOCOUNT ON;
  RAISERROR('Please leave my numbers table alone.', 11, 1);
END

是的,这可以被击败,但必须有人真正不遗余力地去做。如果您雇用的人员可能会这样做,并信任他们对数据库具有通用访问权限,请祈祷这是他们计划造成的最大损害。

是的,如果您删除/重新创建数字表或在其他地方实现它,您可能会忘记重新实现触发器。但您也可能会忘记您可能手动执行的任何处理间隙的操作。


(3) 如果您愿意即时导出数字,则可以完全避免使用数字表。为此,我使用 sys.all_columns 和 sys.all_objects 等目录视图,具体取决于我需要多少个数字:

;WITH n AS (SELECT TOP (10000) n FROM 
  (SELECT n = ROW_NUMBER() OVER
    (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
  ) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!

如果只需要100行,则可以只使用其中一个视图,无需交叉连接;如果您需要更多,您可以添加更多视图。并不是试图让你远离数字表,但这会让你绕过一些限制,例如(a)在每个实例上构建一个数字表以及(b)在哲学上反对这种事情的人(我在我的研究中遇到过很多人)职业)。


顺便说一句,这确实应该出现在产品中。请投票并在以下 Connect 项目中陈述真实的业务用例:

http://connect.microsoft.com/SQLServer/feedback/details/258733/add-a-built-in-table-of-numbers http://connect.microsoft.com/SQLServer/feedback/details/258733/add-a-built-in-table-of-numbers

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何保证统计表的连续性? 的相关文章

  • 使用 DISTINCT 进行查询需要很长时间

    我正在使用 Microsoft Access 2003 我的项目中的一个表单需要很长时间才能向用户显示 这是适用的查询 SELECT DISTINCT tb KonzeptDaten DFCC tb KonzeptDaten OBD Cod
  • PostgreSQL函数中sql语言和plpgsql语言的区别

    我很新数据库开发所以我对下面的例子有一些疑问 函数 f1 语言 SQL create or replace function f1 istr varchar returns text as select hello varchar istr
  • TransactionScope 是否需要开启 DTC 服务?

    根据我的阅读 为了在 NET 中使用 TransactionScope 您需要运行 Windows 中的分布式事务协调器服务 我有那个服务关掉 并且我的应用程序似乎运行相同并且回滚事务没有问题 我错过了什么吗 它如何能够发挥作用呢 我正在运
  • 在 Yii 的标准中如何获得计数 (*)

    我正在尝试构建一个具有以下内容的查询group by属性 我正在尝试得到id和count它一直告诉我count is invalid列名 我怎样才能得到count来自group by询问 工作有别名 伊伊 1 1 11 其他不及格 crit
  • 将表值参数与 SQL Server JDBC 结合使用

    任何人都可以提供一些有关如何将表值参数 TVP 与 SQL Server JDBC 一起使用的指导吗 我使用的是微软提供的6 0版本的SQL Server驱动程序 我已经查看了官方文档 https msdn microsoft com en
  • SQL Server 文件操作?

    使用 SQL Server 2005 如何使用 T SQL 将文件读入 SPROC 所以 假设我有一个像这样的 CSV 文件 ID OtherUselessData 1 asdf 2 asdf 3 asdf etc 我基本上想这样做 Sel
  • 根据数据框中的内容从SQL Server删除行

    我在 SQL Server 中有一个名为的库存表dbo inventory其中包含Year Month Material and Stock quantity 我每天都会收到 csv 文件形式的新库存计数 需要将其加载到dbo invent
  • 处理ON INSERT触发器时,innodb表如何锁定?

    我有两个 innodb 表 articles id title sum votes 1 art 1 5 2 art 2 8 3 art 3 35 votes id article id vote 1 1 1 2 1 2 3 1 2 4 2
  • 如何在Word 2010中从SQL数据库检索数据?

    我想用 MS SQL 数据库中的数据填充 Word 文档 这可能吗 如果可能的话 如何实现 我过去曾通过多种方式做到这一点 这取决于用户是从 Microsoft Word 外部还是从 Microsoft Word 内部启动操作 From I
  • SQLite SQL 查询出现问题[重复]

    这个问题在这里已经有答案了 我正在尝试在 SQLite 3 中运行以下查询 SELECT DISTANCE latitude longitude AS distance FROM country WHERE id NOT LIKE HAVI
  • Rails 中 WHERE 子句中的 ALL 运算符

    关联关系如下图所示 InstructorStudent has many fees Fee belongs to instructor student 我想要获得在所有给定数组中具有每月详细信息的指导学生 如果其中任何一个中不存在每月详细信
  • 复杂的sql树行

    表结构 id message reply id 1 help me 0 434 love to 1 852 didn t work 434 0110 try this 852 2200 this wont 0 5465 done 0110
  • 重建数据库中的所有索引

    我有一个非常大的 SQL Server 2008 R2 数据库 1 5TB 并将在同一个表中的列之间复制一些数据 我被告知该架构有大量索引 并且想知道是否有默认查询或脚本可以重建所有索引 是否也被建议同时更新统计数据 30 个表中的每一个都
  • mysql 详细查询字符串,如通配符

    不知道如何标题我的问题 哈哈 下面是我需要的 我的数据库中的值如下所示 test example 1 test example 2 test example TD 1 这些值的长度可以不同 test example 只是一个示例 某些值将具
  • 插入多行而不重复语句的“INSERT INTO ...”部分?

    我知道我几年前就已经这样做过 但我不记得语法了 而且由于提取了大量有关 批量导入 的帮助文档和文章 我在任何地方都找不到它 这就是我想做的 但语法不完全正确 请以前做过此操作的人帮助我 INSERT INTO dbo MyTable ID
  • PostgreSQL 和锁定

    希望一些比我更聪明的 DBA 可以帮助我找到一个好的解决方案来完成我需要做的事情 为了便于讨论 我们假设我有一个名为 work 的表 其中包含一些列 其中一列表示给定客户端对该行工作的所有权 场景是 我将连接 2 个客户端并轮询表以查找要完
  • 无法批量加载。操作系统错误代码 5(访问被拒绝。)

    由于某些奇怪的原因 我在执行批量插入时遇到问题 BULK INSERT customer stg FROM C Users Michael workspace pydb data andrew out txt WITH FIRSTROW 0
  • SQL Server 2008 R2 内连接无法匹配 varchar 字段,因为它包含特殊字符

    我们正在将 Microsoft SQL Server 2008 R2 用于我们的经典 ASP 应用程序之一 我们有两张表 TableA TableB TableA有以下列 InstName varchar 1024 TableB有这些列 I
  • 作为 UDF 结果的列上的 Where 子句

    我有一个用户定义的函数 例如myUDF a b 返回一个整数 我试图确保该函数仅被调用一次 并且其结果可以用作WHERE clause SELECT col1 col2 col3 myUDF col1 col2 AS X From myTa
  • “必须声明标量变量”错误[重复]

    这个问题在这里已经有答案了 必须声明标量变量 Id SqlConnection con new SqlConnection connectionstring con Open SqlCommand cmd new SqlCommand cm

随机推荐

  • 将 UML 模型保存为 XMI 歧义

    我在维基百科上关于XMI的文章中找到了这样一句话 目前不同版本之间存在一些不兼容性 XMI 的建模工具供应商实现 甚至在互换之间 抽象模型数据 我想知道 尽管使用了记录良好的标准 但工具怎么可能不兼容 在浏览了 UML 和 XMI 的文档以
  • 更新条目向数据库添加新条目

    我正在进行 POST 调用以将一朵花添加到数据库中 但如果 if 语句为 true 我想更新另一个表中的记录 如果该声明不正确 它会毫无问题地添加花 但是当我尝试更新时PinkRoseId使用新的 id 它会创建一条新记录而不是更新旧记录
  • 非常大的 mysql 表和报告

    我正在寻找在 MySQL 中处理大型表的选项 在我的数据库中 很少有表的行数超过 1 3 亿 超过 70GB 并且增长速度非常快 出于报告和分析的目的 我必须运行一些聚合函数 尽管有索引 但查询运行速度非常慢 我尝试制作一些包含合并数据的表
  • 使用 Celery 任务中的 SocketIO 进行服务器推送

    我有一个flask我在其中有许多长时间运行的异步任务 小时 的应用程序 与客户沟通这些任务的状态非常重要 I use celery管理后台任务队列 我目前正在尝试通过以下方式从每个后台线程向客户端广播更新socketIO 这可能吗 是否有更
  • 通过 foursquare API 签入时,我没有出现在此处

    不确定这是否与this https stackoverflow com questions 8744750 foursquare api v2 not getting reply for herenow问题 似乎是 但我不能只评论答案 我还
  • 箭头函数不应返回赋值 no-return-assign

    然而 我的代码在应用程序中工作正常 在提交 husky 运行并给出错误 箭头函数不应返回赋值 no return assign 之前
  • 如何在 ASP.NET Core 6 MVC 应用程序中动态添加控制器

    我需要在 ASP NET Core 6 MVC 应用程序中动态创建控制器 我找到了一些方法可以在一定程度上实现这一目标 但并不完全如此 我可以动态添加控制器 但不知何故它仅反映在第二个请求上 所以这就是我所做的 首先我初始化我的控制台应用程
  • 从 Azure Blob 容器读取 Parquet 数据,而无需在本地下载

    我正在使用 azure SDK avro parquet 和 hadoop 库从 Blob 容器读取 parquet 文件 目前 我正在将文件下载到临时文件 然后创建一个 ParquetReader try InputStream inpu
  • C# HTTP PUT 请求代码的问题

    我正在尝试通过 Amazon S3 已为我生成的 PUT 请求 URL 将文件发送到 S3 我的代码对于小文件工作正常 但在发送几分钟后对于大文件 gt 100 mb 会出错 有错误的是 请求被中止 请求被取消 在 System Net C
  • 如何锁定 Android 设备的屏幕

    我想在我的应用程序中实现屏幕锁定功能 但目前我无法让它工作 我有一个警报对话框 它将通过使用几个按钮请求用户输入 如果用户按 否 我想锁定屏幕 无限期 而不是设定的时间 以编程方式锁定屏幕的最佳方法是什么 我尝试使用以下命令 但是尽管我的对
  • 同一 UIView 中的多个 UIPickerView

    我是 iOS 开发的完全初学者 我想创建一个小型 iOS 应用程序 在此应用程序中 3UIPickerViews应该显示不同的数据 我的问题出在显示器上 我习惯了在 Android 或 Windows 手机上进行开发 但我不明白如何填充UI
  • 预处理器“_AFXDLL”是什么意思?

    我已经搜索过 但没有找到有意义的解释 比如效果是什么 机制是什么 所以我可以理解 一个 有意义的解释 的例子 网上有很多资料解释 DEBUG预处理器 如何打开它将允许assert etc MSDN 第 1 页表示这不适用于 1 常规 DLL
  • 使用 DialogFragment 调用 Activity 时出现 NullPointerException

    我正在将我的对话框转换为DialogFragments 我正在按照说明进行操作here http android developers blogspot com 2012 05 using dialogfragments html但看起来他
  • 为什么使用 ifelse 后必须再次设置 as.Date origin ?有没有更好的办法?

    以下函数确实有效 但最后的 as Date 部分或多或少是不完全理解的反复试验的结果 This function creates a real date column out of year period that is saved in
  • 使用 CursorLoader 进行 GROUP BY

    我如何定义一个GROUP BY查询我的 CursorLoader a 的两个构造函数CursorLoader我看采取任何一个Context or a Context Uri projection selection selectionArg
  • 如何在Android中隐藏SD卡中的文件夹

    我正在开发一个android应用程序 它在应用程序启动时创建一些文件夹 其中包含图像 视频文件和子文件夹 我想在创建时隐藏这些文件夹和文件 当我们在设备中手动访问 SD 卡时 不应看到这些文件夹 如果你想在 Android 或任何基于 Li
  • 让 TextView 在聚焦时变成橙色?

    我有一个文本视图 我将其设置为可点击和可聚焦 当用户使用拨轮等将其聚焦时 如何使其突出显示为橙色 如按钮 TextView tv tv setClickable true tv setFocusable true Thanks 这很容易 这
  • 将外部 URL 加载到模态 jquery ui 对话框中

    为什么不将 ibm com 显示为 400x500px 模式 该部分似乎是正确的 但它不会导致弹出模式出现
  • APT和AOP在同一个项目中,使用Maven

    我必须在同一个 Maven 项目中使用注释处理 apt 和 AspectJ 两者都为自己工作 但我需要根据 apt 创建的代码创建方面 所以我需要二进制编织 原始源文件由apt扩展 如何在 Maven 项目中启用二进制编织 我知道唯一的标准
  • 如何保证统计表的连续性?

    In Joe Celko 提供了 Series 表 其他地方称为 Tally 或 Numbers 的 ANSI SQL 定义 他的定义确保列中的值是唯一的 正数且从 1 到最大值连续 CREATE TABLE Series seq INTE