您的位置:首页 > 数据库

很少看到有人这样写SQL

2009-10-28 23:13 429 查看
很少看到有人这样写SQL

好久没写代码了,想编写一套独立的企业宣传网站,包含前台信息展示及后台数据维护。但都好几天了,我也仅是10月24日这天才写了下面这一点点SQL(MS SQL Server 2000 环境),只因工作忙,下班后已经无心与代码格斗。

/**
* 项目名称:通用企业宣传网站(CorporatePRSite)
*
* 程序设计:邓超(CodingMouse)
* 策划日期:2009年10月24日
*/

/*
* 创建 企业宣传网站(CorporatePRSite)数据库
*/
use master
go
if exists(select name from sysdatabases where name = 'CorporatePRSite')
drop database CorporatePRSite
go
create database CorporatePRSite
go
use CorporatePRSite
go

/*
* 创建 登录模式(loginMode)表
*/
if exists(select name from sysobjects where name = 'loginMode' and upper(xtype) = upper('U'))
drop table loginMode
go
create table loginMode (
-- 登录模式ID
loginModeId int identity(1, 1) constraint PK_loginMode_loginModeId primary key clustered not null,
-- 登录模式名称
loginModeName varchar(20) constraint UQ_loginMode_loginModeName unique nonclustered constraint CK_loginMode_loginModeName check(len(loginModeName) > 0) not null
)
go

-- 添加 登录模式(loginMode)表 测试数据
set identity_insert loginMode on
insert into loginMode(loginModeId, loginModeName) values(1, '开发者模式')
insert into loginMode(loginModeId, loginModeName) values(2, '管理员模式')
insert into loginMode(loginModeId, loginModeName) values(3, '用户模式')
set identity_insert loginMode off
go

-- 查看 登录模式(loginMode)表 测试数据
select loginModeId, loginModeName from loginMode order by loginModeId asc
go

/*
* 创建 账户(account)表
*/
if exists(select name from sysobjects where name = 'account' and upper(xtype) = upper('U'))
drop table account
go
create table account (
-- 账户ID
accountId int identity(1, 1) constraint PK_account_accountId primary key clustered not null,
-- 账户姓名
accountName varchar(20) constraint CK_account_accountName check(len(accountName) > 0) not null,
-- 登录名称
loginName varchar(20) constraint UQ_account_loginName unique nonclustered constraint CK_account_loginName check(len(loginName) > 0) not null,
-- 登录密码
loginPassword varchar(20) constraint CK_account_loginPassword check(len(loginPassword) >= 6 and len(loginPassword) <= 20) not null,
-- 电子邮箱
email nvarchar(50) constraint UQ_account_email unique nonclustered constraint CK_account_email check((len(email) - len(replace(email, '@', ''))) = 1 and (len(email) - len(replace(email, '.' , ''))) >= 1 and charindex('@', email) <> 1 ) not null,
-- 登录模式ID
loginModeId int constraint FK_account_loginModeId foreign key references loginMode(loginModeId) not null
)
go

-- 添加 账户类型(accountType)表 测试数据(刘一、陈二、张三、李四、王五、赵六、孙七、周八、吴九、郑十)
set identity_insert account on
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(1, '刘一', 'liu', 'liu123456', 'liu123456@gmail.com', 1)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(2, '陈二', 'chen', 'chen123456', 'chen123456@163.com', 2)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(3, '张三', 'zhang', 'zhang123456', 'zhang123456@sina.com', 2)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(4, '李四', 'li', 'li123456', 'li123456@qq.com', 3)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(5, '王五', 'wang', 'wang123456', 'wang123456@126.com', 3)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(6, '赵六', 'zhao', 'zhao123456', 'zhao123456@163.com', 3)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(7, '孙七', 'sun', 'sun123456', 'sun123456@hotmail.com', 3)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(8, '周八', 'zhou', 'zhou123456', 'zhou123456@sina.com', 3)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(9, '吴九', 'wu', 'wu123456', 'wu123456@gmail.com', 3)
insert into account(accountId, accountName, loginName, loginPassword, email, loginModeId) values(10, '郑十', 'zheng', 'zheng123456', 'zheng123456@yahoo.com.cn', 3)
set identity_insert account off
go

-- 查看 账户类型(accountType)表 测试数据
select accountId, accountName, loginName, loginPassword, email, loginModeId from account order by accountId asc
go

/**
* 创建 账户(accountView)视图
*/
if exists(select name from sysobjects where name = 'accountView' and upper(xtype) = upper('V'))
drop view accountView
go
create view accountView as
select A.accountId, A.accountName, A.loginName, A.loginPassword, A.email, L.loginModeName
from account A
left join loginMode L
on A.loginModeId = L.loginModeId
go

-- 查看 账户(accountView)视图
select accountId, accountName, loginName, loginPassword, email, loginModeName from accountView order by accountId asc
go

/**
* 创建 城市(city)表
*/
if exists(select name from sysobjects where name = 'city' and upper(xtype) = upper('U'))
drop table city
go
create table city (
-- 城市ID
cityId int identity(1, 1) constraint PK_city_cityId primary key clustered not null,
-- 城市名称
cityName varchar(20) constraint CK_city_cityName check(len(cityName) > 0) not null,
-- 经度
longitude decimal(6, 2) constraint CK_province_longitude check(longitude >= 0 and longitude <= 180) not null,
-- 纬度
latitude decimal(6, 2) constraint CK_province_latitude check(latitude >= 0 and latitude <= 90) not null
)
go

-- 添加 城市(city)表 测试数据
set identity_insert city on
insert into city(cityId, cityName, longitude, latitude) values(1, '北京', 116.46, 39.92)
insert into city(cityId, cityName, longitude, latitude) values(2, '杭州', 120.19, 30.26)
insert into city(cityId, cityName, longitude, latitude) values(3, '天津', 117.2, 39.13)
insert into city(cityId, cityName, longitude, latitude) values(4, '合肥', 117.27, 31.86)
insert into city(cityId, cityName, longitude, latitude) values(5, '上海', 121.48, 31.22)
insert into city(cityId, cityName, longitude, latitude) values(6, '福州', 119.3, 26.08)
insert into city(cityId, cityName, longitude, latitude) values(7, '重庆', 106.54, 29.59)
insert into city(cityId, cityName, longitude, latitude) values(8, '南昌', 115.89, 28.68)
insert into city(cityId, cityName, longitude, latitude) values(9, '香港', 114.1, 22.2)
insert into city(cityId, cityName, longitude, latitude) values(10, '济南', 117, 36.65)
insert into city(cityId, cityName, longitude, latitude) values(11, '澳门', 113.5, 22.2)
insert into city(cityId, cityName, longitude, latitude) values(12, '郑州', 113.65, 34.76)
insert into city(cityId, cityName, longitude, latitude) values(13, '呼和浩特', 111.65, 40.82)
insert into city(cityId, cityName, longitude, latitude) values(14, '武汉', 114.31, 30.52)
insert into city(cityId, cityName, longitude, latitude) values(15, '乌鲁木齐', 87.68, 43.77)
insert into city(cityId, cityName, longitude, latitude) values(16, '长沙', 113, 28.21)
insert into city(cityId, cityName, longitude, latitude) values(17, '银川', 106.27, 38.47)
insert into city(cityId, cityName, longitude, latitude) values(18, '广州', 113.23, 23.16)
insert into city(cityId, cityName, longitude, latitude) values(19, '拉萨', 91.11, 29.97)
insert into city(cityId, cityName, longitude, latitude) values(20, '海口', 110.35, 20.02)
insert into city(cityId, cityName, longitude, latitude) values(21, '南宁', 108.33, 22.84)
insert into city(cityId, cityName, longitude, latitude) values(22, '成都', 104.06, 30.67)
insert into city(cityId, cityName, longitude, latitude) values(23, '石家庄', 114.48, 38.03)
insert into city(cityId, cityName, longitude, latitude) values(24, '贵阳', 106.71, 26.57)
insert into city(cityId, cityName, longitude, latitude) values(25, '太原', 112.53, 37.87)
insert into city(cityId, cityName, longitude, latitude) values(26, '昆明', 102.73, 25.04)
insert into city(cityId, cityName, longitude, latitude) values(27, '沈阳', 123.38, 41.8)
insert into city(cityId, cityName, longitude, latitude) values(28, '西安', 108.95, 34.27)
insert into city(cityId, cityName, longitude, latitude) values(29, '长春', 125.35, 43.88)
insert into city(cityId, cityName, longitude, latitude) values(30, '兰州', 103.73, 36.03)
insert into city(cityId, cityName, longitude, latitude) values(31, '哈尔滨', 126.63, 45.75)
insert into city(cityId, cityName, longitude, latitude) values(32, '西宁', 101.74, 36.56)
insert into city(cityId, cityName, longitude, latitude) values(33, '南京', 118.78, 32.04)
insert into city(cityId, cityName, longitude, latitude) values(34, '台北', 121.5, 25.05)
insert into city(cityId, cityName, longitude, latitude) values(35, '内江', 105.04, 29.59)
set identity_insert city off
go

-- 查看 城市(city)表 测试数据
select cityId, cityName, longitude, latitude from city order by cityId asc
go

/**
* 创建 省份/直辖市(province)表
*/
if exists(select name from sysobjects where name = 'province' and upper(xtype) = upper('U'))
drop table province
go
create table province (
-- 省份ID
provinceId int identity(1, 1) constraint PK_province_provinceId primary key clustered not null,
-- 省份名称
provinceName varchar(20) constraint CK_province_provinceName check(len(provinceName) > 0) not null,
-- 简称
abbreviation varchar(10) constraint CK_province_abbreviation check(len(abbreviation) > 0) not null,
-- 行政中心城市ID
administrationCenterCityId int constraint FK_province_administrationCenterCityId foreign key references city(cityId) not null
)
go

-- 添加 省份/直辖市(province)表 测试数据
set identity_insert province on
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(1, '北京市', '京', 1)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(2, '浙江省', '浙', 2)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(3, '天津市', '津', 3)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(4, '安徽省', '皖', 4)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(5, '上海市', '沪', 5)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(6, '福建省', '闽', 6)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(7, '重庆市', '渝', 7)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(8, '江西省', '赣', 8)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(9, '香港特别行政区', '港', 9)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(10, '山东省', '鲁', 10)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(11, '澳门特别行政区', '澳', 11)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(12, '河南省', '豫', 12)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(13, '内蒙古自治区', '内蒙古', 13)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(14, '湖北省', '鄂', 14)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(15, '新疆维吾尔自治区', '新', 15)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(16, '湖南省', '湘', 16)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(17, '宁夏回族自治区', '宁', 17)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(18, '广东省', '粤', 18)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(19, '西藏自治区', '藏', 19)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(20, '海南省', '琼', 20)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(21, '广西壮族自治区', '桂', 21)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(22, '四川省', '川/蜀', 22)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(23, '河北省', '冀', 23)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(24, '贵州省', '贵/黔', 24)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(25, '山西省', '晋', 25)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(26, '云南省', '云/滇', 26)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(27, '辽宁省', '辽', 27)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(28, '陕西省', '陕/秦', 28)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(29, '吉林省', '吉', 29)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(30, '甘肃省', '甘/陇', 30)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(31, '黑龙江省', '黑', 31)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(32, '青海省', '青', 32)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(33, '江苏省', '苏', 33)
insert into province(provinceId, provinceName, abbreviation, administrationCenterCityId) values(34, '台湾省', '台', 34)
set identity_insert province off
go

-- 查看 省份/直辖市(province)表 测试数据
select provinceId, provinceName, abbreviation, administrationCenterCityId from province order by provinceId asc
go

/**
* 创建 省份/直辖市(provinceView)视图
*/
if exists(select name from sysobjects where name = 'provinceView' and upper(xtype) = upper('V'))
drop view provinceView
go
create view provinceView as
select P.provinceId, P.provinceName, P.abbreviation, C.cityName administrationCenter
from province P
left join city C
on P.administrationCenterCityId = C.cityId
go

-- 查看 省份/直辖市(provinceView)视图
select provinceId, provinceName, abbreviation, administrationCenter from provinceView order by provinceId asc
go

/**
* 创建 账户详细信息(accountDetails)表
*/
if exists(select name from sysobjects where name = 'accountDetails' and upper(xtype) = upper('U'))
drop table accountDetails
go
create table accountDetails (
-- 账户详细信息ID
accountDetailsId int identity(1, 1) constraint PK_accountDetails_accountDetailsId primary key clustered not null,
-- 账户ID
accountId int constraint UQ_accountDetails_accountId unique nonclustered constraint FK_accountDetails_accountId foreign key references account(accountId) not null,
-- 工作单位/公司名称
companyName varchar(100) null,
-- 公司网址
companyWebsite varchar(100) constraint CK_accountDetails_companyWebsite check(charindex('http://', companyWebsite) = 1) null,
-- 所在省份/直辖市ID
provinceId int constraint FK_accountDetails_provinceId foreign key references province(provinceId) not null,
-- 所在城市ID
cityId int constraint FK_accountDetails_cityId foreign key references city(cityId) not null,
-- 联系电话(固话/手机)
telephoneNumber varchar(12) constraint CK_accountDetails_telephoneNumber check(len(telephoneNumber) > 0) not null
)
go

-- 添加 账户详细信息(accountDetails)表 测试数据
set identity_insert accountDetails on
insert into accountDetails(accountDetailsId, accountId, companyName, companyWebsite, provinceId, cityId, telephoneNumber) values(1, 1, '庭燕软件工作室', 'http://blog.csdn.net/CodingMouse', 22, 35, '13547803505')
insert into accountDetails(accountDetailsId, accountId, companyName, companyWebsite, provinceId, cityId, telephoneNumber) values(2, 2, null, 'http://trustqf.spaces.live.com', 12, 12, '13121935832')
insert into accountDetails(accountDetailsId, accountId, companyName, companyWebsite, provinceId, cityId, telephoneNumber) values(3, 3, null, null, 22, 22, '028-80659213')
set identity_insert accountDetails off
go

-- 查看 账户详细信息(accountDetails)表 测试数据
select accountDetailsId, accountId, companyName, companyWebsite, provinceId, cityId, telephoneNumber from accountDetails order by accountDetailsId asc
go

/**
* 创建 账户详细信息(accountDetails)视图
*/
if exists(select name from sysobjects where name = 'accountDetailsView' and upper(xtype) = upper('V'))
drop view accountDetailsView
go
create view accountDetailsView as
select A.accountId, A.accountName, A.loginName, A.loginPassword, A.email, L.loginModeName, D.companyName, D.companyWebsite, P.provinceName, C.cityName, D.telephoneNumber
from account A
left join loginMode L
on A.loginModeId = L.loginModeId
left join accountDetails D
on D.accountId = A.accountId
left join province P
on P.provinceId = D.provinceId
left join city C
on C.cityId = D.cityId
go

-- 查看 账户详细信息(accountDetailsView)视图
select accountId, accountName, loginName, loginPassword, email, loginModeName, companyName, companyWebsite, provinceName, cityName, telephoneNumber from accountDetailsView order by accountId asc
go


就上面这段普普通通的SQL代码,我都已经很久没有看到有人这样去写了,看到的大多是无注释、无必要验证的SQL。

原因有两点:

1、现在的项目大量充斥着三方ORM框架(如Hibernate)的身影,更多时间关心的是对象实体模型,而非数据库模型;

2、所有一切有利的证据都在指示程序设计应该以对象实体模型为开端,数据库模型仅为持久化方案的一种选择而已。

但是,据我所知,目前大量的应用程序正是标榜着“OOD”、“UML”,但最终的持久化载体——数据库却成为真正的“垃圾库”。试想,我曾看到过的一张“人力资源表”,一共有96个列(查询用的SQL语句为:select count(name) from syscolumns where id = object_id('HrmResource')(MS SQL Server 2000 环境)),我曾在一则网文中看到过这样一段数据库优化设计的文字:

逻辑数据库和表的设计
  数据库的逻辑设计、包括表与表之间的关系是优化关系型数据库性能的核心。一个好的逻辑数据库设计可以为优化数据库和应用程序打下良好的基础。

  标准化的数据库逻辑设计包括用多的、有相互关系的窄表来代替很多列的长数据表。下面是一些使用标准化表的一些好处。

A:由于表窄,因此可以使排序和建立索引更为迅速
B:由于多表,所以多镞的索引成为可能
C:更窄更紧凑的索引
D:每个表中可以有少一些的索引,因此可以提高insert update delete等的速度,因为这些操作在索引多的情况下会对系统性能产生很大的影响
E:更少的空值和更少的多余值,增加了数据库的紧凑性由于标准化,所以会增加了在获取数据时引用表的数目和其间的连接关系的复杂性。太多的表和复杂的连接关系会降低服务器的性能,因此在这两者之间需要综合考虑。
定义具有相关关系的主键和外来键时应该注意的事项主要是:用于连接多表的主键和参考的键要有相同的数据类型。

由此可见,这个“人力资源表”的设计是多么地糟糕,并且据了解,这个“人力资源表”所在的数据库上运行的B/S软件的确是运行效率较低,常常执行一个查询都会需要较长的时间来响应。这也证明了上述引用的文字中观点的正确性。

还记得曾经有人问一个问题:“设计数据库时为什么我们通常都会给数据库表设置主键?”,众人答:“为了标识数据行的唯一性。”,我曰:“因为主键是聚集索引(MS SQL Server中的术语),可以加快增删改操作的执行速度。”。很明显,关心数据库的设计的确是可取的。据相关资料显示,大多数应用程序的性能瓶颈并不是应用程序逻辑本身,而在于数据库的设计。

我现在的工作与代码无关,更多的是在客户那里做咨询和需求调研,为了尽快与妻儿能一起生活,很多时候也只是尽力忍耐。无可厚非,我依然更痴迷于代码的世界,对周围看到的软件设计失误造成的问题也太过敏感,这些都包含了程序员的一些基本特征。然而,为了妻儿,我也只能坚持工作,只为当前的工作有足够的休息和很一般的收入。

已经十二点了,又该进被窝了,明天还要上班。各位晚安!

By CodingMouse

2009年10月28日
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: