SQL建模错误--逗号分隔值
最近帮一个客户分析SQL语句的问题,大致经过如下
场景:
委托方有一个用于追踪他们产品的系统,每个产品都会卖给许多客户;但是客户又被从业务上分成两类,一类是带有合作伙伴性质的,这个
合作伙伴通常会给予产品一些建设性的意见,和问题反馈;还有一类就是普通客户了。
程序的第一个版本
create table customer(
id int not null auto_increment, -- 客户id
name varchar(16),-- 客户名
constraint pk__customer__id primary key(id));
-- customer表用于记录客户的信息 create table product(
id int not null auto_increment, -- 产品id
name varchar(32), -- 产品名
partner int not null, -- 合作伙伴id
constraint fk__product__partner foreign key(id) references customer(id),
constraint pk__product__id primary key(id));
-- product表用于记录产品信息 -- 比如说目前的客户有google,facebook,apple; 它们都用了atlas-1.23这个产品;但只有google作为atlas-1.23的合作伙伴
insert into customer(name) values('google'),('facebook'),('apple'); -- 查询customer表中的信息
select * from customer;
+----+----------+
| id | name |
+----+----------+
| 1 | google |
| 2 | facebook |
| 3 | apple |
+----+----------+ -- google 作为atlas-1.23这个产品的合作伙伴
insert into product(name,partner) values('atlas-1.23',1);
这个数据库的逻辑结构有一个问题,就是一个产品是有一个合作伙伴,为了迎合业务数据库的逻辑结构有了第二个版本
程序的第二版
create table customer(
id int not null auto_increment, -- 客户id
name varchar(16),-- 客户名
constraint pk__customer__id primary key(id));
-- customer表用于记录客户的信息 create table product(
id int not null auto_increment, -- 产品id
name varchar(32), -- 产品名
partner varchar(32), -- 合作伙伴名
constraint pk__product__id primary key(id));
-- product表用于记录产品信息 -- 比如说目前的客户有google,facebook,apple; 它们都用了atlas-1.23这个产品;但只有google作为atlas-1.23的合作伙伴
insert into customer(name) values('google'),('facebook'),('apple'); -- 查询customer表中的信息
select * from customer;
+----+----------+
| id | name |
+----+----------+
| 1 | google |
| 2 | facebook |
| 3 | apple |
+----+----------+ -- google 作为atlas-1.23这个产品的合作伙伴
insert into product(name,partner) values('atlas-1.23','google'); --
select * from product;
+----+------------+---------+
| id | name | partner |
+----+------------+---------+
| 1 | atlas-1.23 | google |
+----+------------+---------+ -- 把facebook也设置成atlas-1.23这个产品的合作伙伴
update product set partner=concat(partner,',','facebook') where name='atlas-1.23'; -- 查看atlas-1.23中是否包涵有google & facebook
select * from product;
+----+------------+-----------------+
| id | name | partner |
+----+------------+-----------------+
| 1 | atlas-1.23 | google,facebook |
+----+------------+-----------------+
这个看是完成了业务上的要求,但是它招来了魔鬼
select * from product;
+----+------------+------------------------+
| id | name | partner |
+----+------------+------------------------+
| 1 | atlas-1.23 | google,facebook |
| 2 | alano | facebook,google,Google |
+----+------------+------------------------+
1、这会引起常用的b-tree索引,hash索引失去作用如:select name from product where partner like '%google%';
2、数据的准确性有问题,因为你无法保证不出现google,Google这样的值存在;
3、可扩展性并不强,也就是说如果合作伙伴足够多那么它就会超过varchar(32)的范围;
那么这个要怎么改进呢?
程序的第三个版本就出来了
create table customer(
id int not null auto_increment, -- 客户id
name varchar(16),-- 客户名
constraint pk__customer__id primary key(id));
-- customer表用于记录客户的信息 create table product(
id int not null auto_increment, -- 产品id
name varchar(32), -- 产品名
constraint pk__product__id primary key(id));
-- product表用于记录产品信息 create table product_partner(
id int not null auto_increment primary key,
product_id int not null,
customer_id int not null,
constraint fk__product_id foreign key(id) references product(id),
constraint fk__customer_id foreign key(id) references customer(id));
-- product_partner 表用于保存一个product对应的partner。 insert into customer(name) values('googl');
insert into product(name) values('atlas-1.23'); select * from product;
+----+------------+
| id | name |
+----+------------+
| 1 | atlas-1.23 |
+----+------------+
select * from customer;
+----+-------+
| id | name |
+----+-------+
| 1 | googl |
+----+-------+ insert into product_partner(product_id,customer_id) values(1,1); select * from product_partner;
+----+------------+-------------+
| id | product_id | customer_id |
+----+------------+-------------+
| 1 | 1 | 1 |
+----+------------+-------------+
SQL建模错误--逗号分隔值的更多相关文章
- sql server中单引号拼接字符串(书写错误会出现错误"浮点值 XXXX 超出了计算机表示范围(8 个字节)。“XX”附近有语法错误。")
" ' "(单引号)的运用:在sql server中,两个" ' "(单引号)在拼接字符串的情况下运用,就是表示拼接上了一个" ' "单引号 ...
- SQL Server 错误日志过滤(ERRORLOG)
一.背景 有一天我发现SQL Server服务器的错误日志中包括非常多关于sa用户的登陆错误信息:“Login failed for user 'sa'. 原因: 评估密码时出错.[客户端: XX.X ...
- MS SQL 监控错误日志的告警信息
SQL Server的错误消息(Error Message)按照消息的严重级别一共划分25个等级,级别越高,表示严重性也越高.但是如果你统计sys.messages,你会发现,实际上只有16(SQL ...
- SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- SQL Server代理(5/12):理解SQL代理错误日志
SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 如我们在这个系列的前几篇文章所见,SQL ...
- SQL Server自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- 获取动态SQL查询语句返回值(sp_executesql)
在写存储过程时经常会遇到需要拼接SQL语句的情况,一般情况下仅仅是为了执行拼接后的语句使用exec(@sql)即可. 而今天的一个存储过程却需要获取动态SQL的查询结果. 需求描述:在某表中根据Id值 ...
- sql server 错误日志errorlog
一 .概述 SQL Server 将某些系统事件和用户定义事件记录到 SQL Server 错误日志和 Microsoft Windows 应用程序日志中. 这两种日志都会自动给所有记录事件加上时间戳 ...
- Oracle 在函数或存储过程中执行sql查询字符串并将结果值赋值给变量
请看黄色部分 --区县指标 THEN TVALUE_SQL := 'SELECT TO_CHAR(' || CUR_ROW.MAIN_FIELD || ') FROM ' || CUR_ROW.END ...
随机推荐
- 许多js框架或js库的min版本是怎么做出来的?
如jQuery,Bootstrap,AngularJs,这些都有min版本,代码更加精简,功能却相同.看了源代码,几乎不可读. 这种事情的工具类型叫做“minifier”.请看传送门:Minifica ...
- android ids.xml资源的使用
ids.xml文件例子: XML file saved at res/values/ids.xml: 使用方式: 一:
- HDOJ(HDU) 1465 不容易系列之一(错排)
Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就 ...
- 【转】H264视频编码级别说明profile level Encoder
版权声明:本文为博主原创文章,未经博主允许不得转载. 首先要阐明所谓的AVC其实就是H.264标准,是由ITU-T和ISO/IEC组成的联合视频组(JVT,Joint Video Team)一起开发的 ...
- windows使用命令行杀进程
在windows有时使用任务管理器杀进程,一直杀不掉: 这个时候,可以使用命令行: 先使用tasklist 命令查看当前系统中的进程列表,然后针对你要杀的进程使用taskkill命令 如要杀nginx ...
- 一种调用opencv库的C++工程通用的Makefile模板
第一次自己写makefile,记录一下 #Compilers #CXX=/opt/compiler/gcc-/bin/g++ CXX = g++ #Includes INCLUDE_FLAGS = - ...
- IE浏览器开启对JavaScript脚本的支持
在IE浏览器的"工具"菜单中选择"internet选项",在弹出命令对话框中选择"安全"选项卡.在该选项卡下的"该区域的安全级别& ...
- ibatis的selectkey
在使用ibatis插入数据进数据库的时候,会用到一些sequence的数据,有些情况下,在插入完成之后还需要将sequence的值返回,然后才能进行下一步的操作. 使用ibatis的sel ...
- cocos2d-x anchorPoint
之前一直没有用过anchorPoint,也感觉用这个东西的地方相对比较少的,都是直接使用世界坐标来定位的. 但是,在现在这个项目中,却有同事使用了这个anchorPoint,使用是使用了,但是,在碰撞 ...
- ViewDragHelper详解
2013年谷歌i/o大会上介绍了两个新的layout: SlidingPaneLayout和DrawerLayout,现在这俩个类被广泛的运用,其实研究他们的源码你会发现这两个类都运用了ViewDra ...