关于数据表结构的学习

写在前面:
我非常庆幸的事 在前公司接触过一些表结构的知识和简单的SQL,后端产品经理越想进阶,数据结构化的思维就越发重要(感觉大学概率与数理统计没好好学真是不应该),今天和架构师争执的流程,唯一没有diss成功的地方,就在于流程设计虽然更简洁,却无从取数,所以今天跳出促销,补一补表结构


提升产品经理“技术思维”:学习数据表结构知识

产品转技术难度比较大,学习数据表结构就门槛低很多,对产品设计的作用也很明显。本文会简单介绍一些产品设计中会用到的数据表结构方面的思考,希望对各位有所帮助。

关于数据表结构的学习_第1张图片
image

程序是怎么运行的呢?

简单来说,就是去指定的位置(表)取数据,完成运算,放到指定的位置(表)存起来或展示出来。

那么,怎么保证取到的/存到的数据是按我们预想的方式来的呢?这就涉及到表结构问题了。

数据表是由表名、表中字段、字段内容组成。本文主要围绕字段划分及字段定义两个部分,介绍在产品设计中需要用到的表结构知识。

一、字段分类

要完成一个流程(运算),我们需要诸多数据(字段),这么多字段是一张表还是多张表呢?

我们可以以商品上架为例,简单分析一下。

比方说,仓库现在还有可口可乐50个,进价2.5元,售价3.5元。

1号货架只剩5个可乐,小王在19/6/24日15:20:12向该货架上架20个,预计放在货架第4层;因为新货架促销,打折价3元。

首先,所有相关信息排列:

image

实际业务会比这个字段更多,全在一张表里储存虽然看上去清晰,但是缺点也很明显——因为将主体相关的属性、流水、维度等数据全部混在一起,势必造成大量的数据冗余。

我们按数据类型拆为属性表和流水表。

其中属性表分为商品SKU和货架;流水表为上架操作过程。整理后如下:

关于数据表结构的学习_第2张图片
image

首先,看一下商品表:

(1)商品属性(类别,名称等)跟商品流水(进货、出货)混在一起,可以进一步拆分。

(2)“仓库剩余个数”,可能进货的要改、上架的要改、盘点的要改,多个地方都会对这个字段作用。这种情况可以通过实时计算,比写入覆盖的方式更为准确。

所以调整后会改为:

image

注:前台展示的余量实时计算,不落表。

可以看到商品流通和之前的上架表非常类似,只相差一个货架编号。

假设我们把仓库看做一个大货架,设为0,两表合并整理后:

关于数据表结构的学习_第3张图片
image

再来看货架表,“商品种类数”适用实时计算,不落表。(类似前文仓库余量计算)。

还有一个问题非常突出——商品详情这栏内容特别多。

非结构化数据,不便处理,且与其他表内容重复(比如商品名称和售价)。同样的字段最好只在一个地方维护,避免表之间的数据冲突。商品名称很明显放在商品属性里。

那售价这个字段应该放在商品还是货架上的商品详情?

这其实跟业务模式相关,放在商品里方便全局管理,但是单个货架不能实现差别化定价;相反,放在货架上,同一商品在不同货架上可以设置不同售价,缺点是修改调整比较困难。

根据我们的业务情况,售价主要是统一管理,放在了商品属性;折扣主要是单个货架进行,所以折扣价放在了货架的商品详情。

调整后如下:

image

数据结构确认之后,页面内容设计就比较清晰了:

【商品】

关于数据表结构的学习_第4张图片
image

【货架】

关于数据表结构的学习_第5张图片
image

【货架详情】

关于数据表结构的学习_第6张图片
image

【商品流转】

关于数据表结构的学习_第7张图片
image

注:在实际产品中,页面入口可能带有一些参数,比如上图如果是点击“进货”按钮的弹出框,就无需再手动选择交易类型。

二、字段类型

前面从大的范围上介绍了字段的划分,细节上单个字段的类型、长度也需要加以关注。

一些常用的字段类型:

关于数据表结构的学习_第8张图片
image
关于数据表结构的学习_第9张图片
image
关于数据表结构的学习_第10张图片
image

在字段类型上,我也遇到过一些坑,举两个例子说明一下:

我在P2P公司上班,用户会发布很多借款,有个字段是表示借款类型,比如listingtype。

我们绝大多数的标都是普通标,穿插一点点其他类型。总类型不超过5种,所以当时字段类型是tinyint,范围0-255。

后来有段时间我司发展与合作机构的合作标,当时我做配置系统,设计成每个合作单位分配一个listingtype。

跑着跑着有一天,研发反应过来了,说:总数就255,你再加就爆了。

后来的解决办法是将合作标统一一个listingtype,然后同一类型下,每家单位再各自分配一个sublistingtype。

再举一个例子,还是这个合作标的时候,上线之后,利息计算错误。研发查了一圈,是建表的时候利率字段用了默认的DECIMAL(18,0),导致导入数据时被四舍五入。

三、总结

当然,你可以说:表结构不是研发自定义的吗?但这也不能全是研发的锅,一是研发可能不清楚整个产品的规划,或者说随着业务变化,原本适合的字段类型变得不再适合。

另一方面,并不是所有产品都是从零开始,有的可能是后来加入进行老产品的版本迭代。这种产品在设计之前,了解原先的表结构及字段类型,就能避开很多坑。而且相比前端展示层,数据层上的坑,一般都是大坑,改起来也困难更多。

大家都知道,产品有技术背景会更方便沟通。技术入门也许太难,表类知识入门就简单多了。

本文抛砖引玉,希望大家能往此方向去提炼一下自己,相信会给产品工作带来较大助益。


重温SQL知识

作为一枚数据产品经理,需要掌握基本的SQL查询语句技能,之后才能进一步了解与搭建数据仓库、元数据、指标字典体系。本文首先介绍MySQL基本知识。

一、了解数据库
模式:关于数据库和表的布局及特性的信息;
行是表中的记录,列是字段;
主键列中的值不能修改,且不能重用;
数据库中包含表及其它相关sql结构。
二、检索数据
2.1 select语句
检索所有列:select * from products

2.2 排序检索数据
order by:select prod_name from products order by prod_name。

注意:order by的子句必须是select语句的最后一个子句。

按多个列排序:select prod_id,prod_name,prod_price from products order by prod_price,prod_name。那么输出结果先按prod_price排序,然后再将排序后的结果按prod_name排序。

按列位置排序:select prod_id,prod_name,prod_price from products order by 2,3。语句与上一句结果相同。

降序排序(系统默认升序):order by prod_price DSC,prod_name。则结果先按prod_price降序排序,再按price_name升序排序。

三、过滤数据
(1)使用where子句(在from之后)

范围值检查:between and:where prod_price between 5 and 10。
空值检查:where prod_price is NULL。语句返回没有价格的所有产品(空字段,不是价格为0)
(2)使用组合where子句

AND操作符:where vend AND prod_price<=4 #检索由供应商DLL01制造且产品价格低于4美元的所有产品注意AND用在where子句中的关键字,用来指示检索满足所给定条件的行。
OR操作符:where OR OR用在where子句中的关键字,用来表示检索匹配任一给定条件的行。
AND,OR相结合(AND优先级比OR高):所以注意使用圆括号,where (vend or vend) and prod_price>=10。
IN操作符:where vend_id in(‘DLL01′,’BRS01’),其功能与where or相当。
NOT:否定跟在它之后的任何条件(mysql不支持此操作符), where NOT vend #检索除DLL01之外所有供应商的产品(此句等价于where vend_id <> ‘DLL01’) #NOT一定要紧跟在where后。
(3)用通配符进行过滤(通配符:用来匹配值的一部分的特殊字符,用于“字符串”),使用LIKE+通配符

百分号(%):where prod_name like ‘Fish%’ #检索任意以Fish起头的词(匹配单个或多个字符)。
下划线(_ ) : where prod_name like ‘Fish__’ #检索出的字符必须为Fish+两个字符 (与%能匹配0个字符不一样,_必须匹配一个字符,不能多也不能少)。
方括号([]):where contact like [JM]% #[JM]匹配任何以J,M开头的人名,但它也只能匹配单个字符,为此在[]后加%,则可匹配多个字符。(若改为[^JM],则为检索不以J,M起头的任意联系人名,等价于:where NOT contact like [JM]%)。
四、创建计算字段
(1)拼接字段(将值联结到一起构成单个值)

concat函数(mysql用):select concat(vend_id,’ (‘,vend_country,’)’) #select语句联结以上4个元素。
‘+’号(Access,SQL Server,Sybase使用):select vend_id + ‘ (‘ + vend_country + ‘)’。
‘||’号(DB2,Oracle使用):select vend_id || ‘ (‘ || vend_country || ‘)’。
TRIM函数:RTRIM()去掉值右边所有空格,LTRIM()去掉值左边所有空格,TRIM()去掉值两边所有空格。
AS关键字:给联结字段取别名。
完整联结字段语句: select RTRIM(vend_id) + ‘ (‘ + TRIRM(vend_country) + ‘)’ AS vendor_title FROM Vendors ORDER BY vend_name。
(2)执行算数计算

五、使用视图
视图是虚拟的表,视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的,在更改这些表中的数据时,视图将返回改变过后的数据。

(1)视图的规则和限制

视图可以嵌套;
禁止在视图查询时使用ORDER BY语句。
(2)创建视图(creat view)

利用视图简化复杂的联结;
用视图重新格式化检索出的数据;
用视图过滤不想要的数据(where子句);
使用视图与计算字段。
六、使用存储过程
为以后的使用而存储一条或多条SQL语句的集合。

七、管理事务处理
(1)什么是事务处理

事务管理用来管理必须成批执行的SQL操作,以保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组数据不会中途停止,它们或者作为整体执行,或者完全不执行(除非明确指示)。

如果没有错误发生,则整组语句写到数据库表,如果发生错误,则进行回退(撤销)以恢复数据库到某个已知且安全的状态。

(2)几个术语

事务(transction):一组SQL语句;
回退(rollback):指撤销指定SQL语句的过程;
提交(commit):指将未存储的SQL语句结果写入数据库表;
保留点(savepoint):指事务处理中设置的临时占位符,你可以对它发布回退(与回退整个事务处理不同)。
(3)可以回退哪些语句

可管理INSERT,UPDATE,DELETE语句,不能回退SELECT语句也不能回退CREATE,DROP操作。事务处理中可以使用这些语句,但回退时它们不被撤销。

(4)控制事务处理

创建占位符:

mysql:savepoint delete1;
sql server:save trasaction delete1; #delete1为此占位符的名字。
rollback:#撤销整个事务处理

rollback to delete1;
rollback transaction delete1;#回退到保留点delete1;
八、使用游标(cursor)
游标不是一条select语句,而是被该语句检索出来的结果集,在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或更改。

声明:declare
打开:open cursor
检索:fetch… into…
关闭:close
九、了解高级SQL特性
约束:管理如何插入或处理数据库数据的规则

主键:一种特殊约束

外键:可帮助防止意外删除,唯一约束:与主键类似但区别于主键


希望读完的你也有所收获

原文:http://www.woshipm.com/pmd/2521501.html
http://www.woshipm.com/pmd/1161098.html

你可能感兴趣的:(关于数据表结构的学习)