最新评论
写的不错,虽然不是很有帮助,不过看的出很用心,希望能够深入研究下,比如说池的概念,对象的集成。
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 19:47
--引用--------------------------------------------------
朝晖的.net: @楼主
2. 一个荒唐的 T-SQL 语句
最后楼主要表达的结论是什么?我一直没看明白。
我们到底应不应该用order by?
应用了order by(没有使用top)的标准查询返回的是一个游标,但是我们经常写这种eg:
select * from tableA where tableA.id = '***'
order by tableA.SortColumn;
楼主把结论告诉我吧··看得我点郁闷. :^(
4. 如何利用 T-SQL 编程满足一个苛刻的需求
对于特殊要求的列值,我们一般在程序里实现,把复杂逻辑写在脚本里,感觉维护成本有点高,我的拙见,我也是这么做的。楼主感觉呢?
--------------------------------------------------------
第一个问题就是,理论是上荒唐的,但是T-SQL却支持这种非标准的做法,如果在实践中我们找不到更好的途径快速解决问题的时候,我们使用了SELECT TOP ……ORDER BY来生成派生表的话,也无可厚非。
但是如果考虑到不同生产厂家的数据库产品之间迁移自己的SQL脚本的话,一切都按照 ANSI 的标准来编写 SQL 语句才是正确的做法,所以我给出的答案不在于我,而在于大家自己的实际情况,呵呵。
第二个问题,放在应用程序中处理也无可厚非,但是就这个我实际工作中的示例来说,对于我,利用 T-SQL 来实现的成本比在应用程序中利用更为复杂的逻辑实现更低,呵呵。
re: 关于 T-SQL 的几点小九九 (1) 朝晖的.net 2009-06-08 19:36
@楼主
2. 一个荒唐的 T-SQL 语句
最后楼主要表达的结论是什么?我一直没看明白。
我们到底应不应该用order by?
应用了order by(没有使用top)的标准查询返回的是一个游标,但是我们经常写这种eg:
select * from tableA where tableA.id = '***'
order by tableA.SortColumn;
楼主把结论告诉我吧··看得我点郁闷. :^(
4. 如何利用 T-SQL 编程满足一个苛刻的需求
对于特殊要求的列值,我们一般在程序里实现,把复杂逻辑写在脚本里,感觉维护成本有点高,我的拙见,我也是这么做的。楼主感觉呢?
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 18:38
--引用--------------------------------------------------
耳根、请静: null 和 '' 之间有区别吗?
--------------------------------------------------------
在SQL中两者也截然不同,NULL 表示真正的空值,对于任何数据类型来说均是,等同理解为没有任何输入值。
而'' 表示的具体含义是空字符串,只出现在字符串类型(定长或者可变长)中,在SQL Server 中你看到是一片空白。
如果是在应用程序中显然也是有区别的,数据库中的空字符串对应于.NET 中的System.String.Empty,也就是我们常说的""。
在应用程序中,判断一个字符串是否为空值或者空字符串的方法,我自己封装如下:
#region 根据输入的字符串返回检查其是否为空引用或空字符串的结果的方法
/// <summary>
/// 作者:张亮
/// 功能:根据输入的字符串返回检查其是否为空引用或空字符串的结果
/// 时间:2008-06-24
/// </summary>
/// <param name="inputString">输入的字符串</param>
/// <returns>
/// isNullOrEmpty:
/// true 表示输入的字符串是空引用或空字符串
/// false 表示输入的字符串不是空引用或空字符串
/// </returns>
public static bool CheckStringIsNullOrEmpty(string inputString)
{
bool isNullOrEmpty = false;
string str = null;
/*
* 2008.10.8号 有必要重新回顾下当初写该方法的思路
* 如果不判断 inputString 是否为 null,而直接使用 inputString.Trim() 替换
* switch (str) 中的 str 的话,当 inputString = null 就会抛出异常。
*
* 为防止输入的字符串只作了声明(即赋值为null),而并非在托管堆中分配空间,
* 则声明一个中间变量 str,当 inputString = null 其默认等价于 str = null,
* 而 inputString != null 时则将 inputString.Trim() 赋值给 str。
*/
try
{
if ( inputString != null)
{
str = inputString.Trim();
}
switch (str)
{
case null:
isNullOrEmpty = true;
break;
case "":
isNullOrEmpty = true;
break;
default:
isNullOrEmpty = false;
break;
}
}
catch ( Exception exp )
{
throw exp;
}
return isNullOrEmpty;
}
#endregion
re: 关于 T-SQL 的几点小九九 (1) 耳根、请静 2009-06-08 17:54
null 和 '' 之间有区别吗?
re: 关于 T-SQL 的几点小九九 (1) Asidy 2009-06-08 17:35
写的不错,项一下
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 17:20
--引用--------------------------------------------------
周强: 各位园友,我们不能读死书,我们要通过书中的所讲去理解,然后会思考。NULL确实会和SQL 带来额外的负担,但是我们是不是因为此就对NULL带有一种惯性的偏见呢?NULL和NOT NULL就性能和存储空间方面来说,我觉得不用做太多考虑,如果从程序的复杂度来说,倒是可以权衡一下。
--------------------------------------------------------
对于我来说,在应用程序中最讨厌处理的就是 NULL 值的情况,也常常成为我程序中隐形的BUG来源,所以当我获得一种能更好规避 NULL 值的做法时,我跟愿意在 T-SQL 程序相对编写复杂的脚本语句,而不愿意在应用程序中每每考虑字段是否存在空值的情况,如有该如何处理。
对于 NULL 的偏见并非来自于使用 T-SQL 编程和数据库,而是来自于应用层处理字段时各种需要考虑的逻辑判断。
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 17:12
--------------------------------------------------------
那就讨论存储引擎吧。
SQL SERVER 2005和SQL 2000来比较,我觉着在存储"格式"方面,包括在工作原理方面,微软真没做什么改进,除了为了新功能特性的需要(比如表分区等)而导致了一些存储“格式”方面的变化外,其它几乎没什么变化。君不见《SQL 2000 技术内幕》与《SQL 2005 存储引擎》两本书在存储引擎方面95%的内容雷同?我猜想,SQL SERVER 2005有可能在存取算法上有所改进。
SQL SERVER 2005性能比SQL 2000好,我觉得SQL 2005在关系引擎和隔离级别方面倒是下了大功夫,存储引擎真说不准究竟有没有下功夫。
--------------------------------------------------------
其实推翻一个已经成熟的“工作原理”模型,建立一套新的体系真不是件容易的事情,微软举步维艰只是整个业界的一个缩影罢了。
Lubor kollar 听见你的话肯定会比较开心的,他引导的团队在关系引擎上还是应该下了不少功夫的。至于存储的一些底层算法的改进一定是有的,只是这样真正的内幕公布于市面主流的技术书籍之中,恐怕有失稳妥,呵呵。《SQL 2000 技术内幕》是一部巨头,我只是在书店翻阅过,未尝收入囊中,倒是 《SQL 2005 技术内幕》前三部已经堆积在床头,每日必读,而一直纳闷为什么不引进哪怕“调优”,哪怕是便宜的英文影印版也好,呵呵。这些书中的说描述的“内幕”对于我来说,更像是那些官方文档意犹未尽的细节之处,让人读了能够知其所以然,这样的数据读来,对于经历过实践折磨之后的我来说,受益良多,呵呵。
各位园友,我们不能读死书,我们要通过书中的所讲去理解,然后会思考。NULL确实会和SQL 带来额外的负担,但是我们是不是因为此就对NULL带有一种惯性的偏见呢?NULL和NOT NULL就性能和存储空间方面来说,我觉得不用做太多考虑,如果从程序的复杂度来说,倒是可以权衡一下。
--引用--------------------------------------------------
一个数据库产品的核心就是存储引擎,引擎的优良直接决定了这个产品的生命力,从我使用 SQL Server 2000 和 SQL Server 2005(使用时间不长),每一次引擎的优化和升级带来的各种层出不穷的特性和性能上的提高是非常明显的。
SQL Server 2008刚出来那会使用过几天测试版之后再也没有触碰。在数据库上扑的时间越多,就会越发觉得自己需要了解和学习的东西实在太多,作为一个程序员,尤其是一个应用软件开发的程序员,多了解多关注一些数据库深层次的东东对于开发来说是非常有帮助的。
--------------------------------------------------------
那就讨论存储引擎吧。
SQL SERVER 2005和SQL 2000来比较,我觉着在存储"格式"方面,包括在工作原理方面,微软真没做什么改进,除了为了新功能特性的需要(比如表分区等)而导致了一些存储“格式”方面的变化外,其它几乎没什么变化。君不见《SQL 2000 技术内幕》与《SQL 2005 存储引擎》两本书在存储引擎方面95%的内容雷同?我猜想,SQL SERVER 2005有可能在存取算法上有所改进。
SQL SERVER 2005性能比SQL 2000好,我觉得SQL 2005在关系引擎和隔离级别方面倒是下了大功夫,存储引擎真说不准究竟有没有下功夫。
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 15:05
--引用--------------------------------------------------
sweepercn: 楼主那个关于生成唯一编码的逻辑有点看不懂,
以数据本表的planid的值本身做计数器,不就可以了,
为什么还要再去另找一表来做计数器?是不是有点把简单问题复杂化,原本只需要锁定一个表,现在一个事务锁定两个表,是不是太多余了。我想象的这样:
在本表里设planid维一值索引。
1、从本表最出最大数。
2、用TSQL语直接加1.
3、开始事务,插入数据。
还望楼主解惑。
--------------------------------------------------------
恩,您可能没有仔细看需求的由来,老板需要的变化规则如下:
例如现在是6月,那么生成的编号是 DP-P-09060001起始,一直到6月截止,按照业务需求最大量,采购发生的笔数不会超过 9999 笔,也就是我假设 6月最大的编号值为:DP-P-09069999。
那么到了7月份,DP-P-09070001 ~ DP-P-09079999
一下以此类推,之所以单独编写一个同步序列生成机,是为了能够没月1号00:00分后方式有数据插入发生,序列机会自动重新归零,从每月第一笔单开始重新计算,如果是使用你那种方式因为是不能满足这样的编号规则的。
其实,我这里还存在缺陷,我已经在 T-SQL 语句中用注释写明了,就是如果服务器时间被异常更改,如果是往后推迟了无所谓,现有规则依然可以运行,但是服务器时间被回拨,就是本来是6月,现在变成了5月,而5月的记录最大数值是DP-P-09051111,而此刻序列机中编号值为1000,那么此刻在插入数据,就会报错:PlanID 唯一性……。也就是说理应增加一道机制,检查插入的最后一个PlanID的年月份是否匹配,那么一旦发现日期异常,应该是去取出服务器当前月最大PlanID 的后4位值,写入到序列机中,从而继续在当前月的最后一个 PlanID 后继续连续生成新的 PlanID。
实在是有点绕,可能是我把问题复杂化了,考虑的东西太多了,等我沉静下来,把整个思路重新梳理成一篇文字,这样就方便理解了,呵呵。
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 14:46
--引用--------------------------------------------------
周强: NULL 和 NOT NULL 完全看应用,怎么方便就怎么用吧。
1. NULL 和 NOT NULL对存储空间的影响。对于定长类型的字段,如果某个字段允许为NULL ,则对于一行数据,首先至少要增加一个字节来作为NULL位图,并且实际存储的时候即使这个定长列不存储任何数据,这个列的空间依然是要分配的,所以,对与一个定长字段允许为NULL,反而会增加存储空间;如果是变长字段允许为NULL,在绝大部分情况下,确确实实会少一点空间。对于绝大部分系统,不论是定长为NUL增加空间,还是变长为NULL节省空间,个人认为不用太在意,怎么方便使用怎么用。如果你确实非常在意这几个字节的空间,那么我建议你用SQL 2008.在SQL 2008中NULL位图这一列已经被稀疏化,在一行数据中,如果有一列允许为NULL,存储引擎已经不用再为每一行数据都分配至少一个字节来做NULL位图了。
2.对于存储引擎的复杂度。允许一个列为NULL,肯定会增加存储引擎处理数据的复杂度。因为NULL这个值不算是一个值,存储引擎只能维护一个位图,这个位图上的值为1,则对应的列为NULL。但这个对性能的影响很小,完全可忽略。
--------------------------------------------------------
一个数据库产品的核心就是存储引擎,引擎的优良直接决定了这个产品的生命力,从我使用 SQL Server 2000 和 SQL Server 2005(使用时间不长),每一次引擎的优化和升级带来的各种层出不穷的特性和性能上的提高是非常明显的。
SQL Server 2008刚出来那会使用过几天测试版之后再也没有触碰。在数据库上扑的时间越多,就会越发觉得自己需要了解和学习的东西实在太多,作为一个程序员,尤其是一个应用软件开发的程序员,多了解多关注一些数据库深层次的东东对于开发来说是非常有帮助的。
re: 关于 T-SQL 的几点小九九 (1) WizardWu 2009-06-08 14:43
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html
设计字段时,若其值可有可无,最好也给一个默认值,并设成「不允许 NULL」(一般字段默认为「允许 NULL」)。 因为 SQL Server 在存放和查询有 NULL 的数据表时,会花费额外的运算动作
参考书籍:
SQL Server 2005 Performance Tuning 性能调校:
作者:胡百敬、姚巧枚、刘承修
电子工业出版社,
ISBN:978-7-121-06296-4
http://www.china-pub.com/39978
http://space.itpub.net/1818400/viewspace-432950
re: 关于 T-SQL 的几点小九九 (1) sweepercn 2009-06-08 14:08
楼主那个关于生成唯一编码的逻辑有点看不懂,
以数据本表的planid的值本身做计数器,不就可以了,
为什么还要再去另找一表来做计数器?是不是有点把简单问题复杂化,原本只需要锁定一个表,现在一个事务锁定两个表,是不是太多余了。我想象的这样:
在本表里设planid维一值索引。
1、从本表最出最大数。
2、用TSQL语直接加1.
3、开始事务,插入数据。
还望楼主解惑。
re: 关于 T-SQL 的几点小九九 (1) 真的,这家伙很懒. 2009-06-08 13:41
楼主真的很细心,异常情况下服务器日期时间的更变都考虑到了.这是很多开发人员所欠缺的.
@铁甲依然在
设置成NOT NULL,一般都会设置一个默认值,所以对于INSERT,方便性方面是不会有什么问题的。
NULL 和 NOT NULL 完全看应用,怎么方便就怎么用吧。
1. NULL 和 NOT NULL对存储空间的影响。对于定长类型的字段,如果某个字段允许为NULL ,则对于一行数据,首先至少要增加一个字节来作为NULL位图,并且实际存储的时候即使这个定长列不存储任何数据,这个列的空间依然是要分配的,所以,对与一个定长字段允许为NULL,反而会增加存储空间;如果是变长字段允许为NULL,在绝大部分情况下,确确实实会少一点空间。对于绝大部分系统,不论是定长为NUL增加空间,还是变长为NULL节省空间,个人认为不用太在意,怎么方便使用怎么用。如果你确实非常在意这几个字节的空间,那么我建议你用SQL 2008.在SQL 2008中NULL位图这一列已经被稀疏化,在一行数据中,如果有一列允许为NULL,存储引擎已经不用再为每一行数据都分配至少一个字节来做NULL位图了。
2.对于存储引擎的复杂度。允许一个列为NULL,肯定会增加存储引擎处理数据的复杂度。因为NULL这个值不算是一个值,存储引擎只能维护一个位图,这个位图上的值为1,则对应的列为NULL。但这个对性能的影响很小,完全可忽略。
re: 关于 T-SQL 的几点小九九 (1) 铁甲依然在 2009-06-08 13:10
呵呵,学习了!不过,觉得把所有的字段都设置成not null的话,有时候会出现一些小小的问题,特别对于insert操作的时候.
当然,把字段设置成not null的话,对于具体事务的操作上会有很大的便利.
re: 关于 T-SQL 的几点小九九 (1) rainnoless 2009-06-08 12:21
--------------------------------------------------------
要处理 NULL 值给存储引擎增加了复杂度,如果允许 NULL,在访问每一行的时候 SQL Server 都必须对这个 bitmap 进行解码
-------------------------------------------------------
本人正在进一步研究中,参考资料可以去查阅《SQL Server 2005 技术内幕 系列》,主要可以翻阅“存储引擎”这本。或许查阅其他和 SQL Server 存储引擎相关的书籍应该都有。我阅读者一套理论著作之后,感觉处理 NULL 值绝对比除非 NOT NULL 值要来的麻烦,在我最近数月的实际工作中,我也尽量避免显示声明字段为NULL值,当然我处理的数据量并非海量,最多达到百万级。
其实让数据库旁边一个字段的值是否真的为空值确实比确认一个值为NOT NULL要复杂的多。如果大家曾经在 T-SQL 中大量使用过 IS NULL ,却总是感觉查询所得的记录有所缺失的时候,就会有许多解不开的疑惑。
以我之前工作中处理 NULL 值的感触来说,我非常赞同Kalen Delany的说法: 可以说 NULL 值是应用程序 BUG 的根源之一。呵呵。
--------------------------------------------------------
就像我平时设计数据库时会把外键约束会加上,但是真正的发布时,会把约束全部去掉,因为程序肯定会对数据链的完整性做判断,这些约束在我看来,可能只是重复劳动!
---------------------------------------
我公司现有的平台,数个数据库中的表都没有外键引用的关系,现在每张表中垃圾数据无数,就是想清理也有点力不从心。不设置外键,的确方便了各种表中数据的删除方便,表与表之间没有任何关联,所谓的联系都是凭借着“实现上的关联”,在人员更替数次之后,文档缺失不明,表数量庞大的时候,就会晕头转向了,这种做法真的是极大破坏了数据的完整性。
更有甚,不是每个应用程序的开发者,都会极度关注利用“事务”来完整维护这些没有外键引用的表与表之间的“更新、删除”等,如果能够做到不设置外键引用,利用编写大量的 T-SQL 语句来维护表与表之间逻辑上的关系,我想会得不偿失的。
还有,任何应用程序上的业务逻辑,哪怕是服务器端的业务逻辑判断,都应该视为“可疑”的,在数据库设计时加上一定的“约束”是非常必要的,这是最后一道防线,并非一种多余,对数据库的负担也并非想象中那么严重。
re: 关于 T-SQL 的几点小九九 (1) lovkooo 2009-06-08 11:45
--引用--------------------------------------------------
rainnoless: --引用--------------------------------------------------
Pandora: NULL是不是会比NOT NULL省很多空间?
--------------------------------------------------------
不知道您的推论从何而来,决定物理空间的大小,并非由 NULL 和 NOT NULL来决定啊?呵呵。
--------------------------------------------------------
我也担心会出现空间存储上的问题!存入默认值的话,肯定会在增加数据库的大小,普通的系统对性能各方面没有太多苛求的没什么关系,如果是海量的数据情况,比如是淘宝等大型的网络平台,可能这样问题可能就被放大了,存储空间的增加,同时应该还会增加数据读取时的IO操作!我觉得是不是可以为空,可以根据程序的需要来决定,至于默认值可以在程序访问数据库时对NULL项绑定到对象(一般是实体对象)时对对象赋上默认值,毕竟cpu的速度以比IO操作来得快得多!
到于NULL与Not NULL时数据库要维护对“要处理 NULL 值给存储引擎增加了复杂度,如果允许 NULL,在访问每一行的时候 SQL Server 都必须对这个 bitmap 进行解码”这个没有了解过(这个资料如果有的话还请博主给小弟参考下),但是个人感觉上来说,可能NOT NULL的情况,数据库可能要对数据存储时要做NOT NULL的检测,反而可能会增加数据库的负担(特别声下,这个只是我的感觉,不好意思),就像我平时设计数据库时会把外键约束会加上,但是真正的发布时,会把约束全部去掉,因为程序肯定会对数据链的完整性做判断,这些约束在我看来,可能只是重复劳动!