3.产品经理学编程
3.1 产品经理为什么要学编程
对于产品经理这一综合性职能来说,具备一定的技术知识,不论是在与工程师工作的配合中,还是在对技术产品的理解上,都能起到非常大的帮助作用。所以,掌握一定的编程知识,对于了解技术产品和技术实现思维都有一定的好处。
什么是编程语言:
编程语言是程序设计人员与计算机进行交互的指令集,在计算机中任何逻辑和表达都可以通过编程语言来实现。对于同一个产品功能,我们可以用不同的编程语言来开发。
选用哪种编程语言一般取决于系统架构师综合衡量后的选择,系统架构师就是软件产品的技术总设计师,负责规划和选用技术实现方案,类似于建筑设计师的角色。不同的系统需要根据系统特性选择合适的编程语言。
3.2 主流编程语言介绍
每一位工程师都有自己擅长的语言,作为非技术产品经理,一定要区分不同的编程语言,如果让一位只开发Android应用的工程师去改iOS应用的代码,或者做客户端的同学去帮助服务端的同学开发,那会成为笑话的。当然,也有所谓的全栈工程师,精通多门技术,可以跨领域工作。下面介绍几种主流编程语言:
C语言:C语言运用于个人计算机、大型和超大型计算机、路由器以及可编程的集成电路里。C语言起源于20世纪70年代,其奠基人是美国人丹尼斯里奇(Dennis Ritchie),他被成为“C语言之父”,同时也是早期非常有名的操作系统Unix的发明人,前文提到的Linux系统很大程度上是基于Unix系统的思想演化而来的。C语言的出现开启了现代编程语言发展的序幕,后来的C++、Java等编程语言都是基于C语言发展而来的。
Java:Java语言也是如今主流编程语言之一,以其跨平台、通用性和安全性的特点被广泛使用。Java是一门面向对象的语言,相对于C语言等面向过程的语言来说,Java的灵活性更高,同时其抽象现实世界的特点对于程序设计人员的学习和理解也更用帮助。
PHP:在Web开发领域,一门比较主流的编程语言就是PHP(PHP:Hypertext Preprocesspr)。PHP是一种开源脚本语言,脚本语言通常以文本形式被保存,只有在调用时进行解释和编译,相对于C语言或者Java语言来说,PHP更加轻量化且更灵活,PHP吸收了C语言和Java的特点,学习成本较低,主要应用于Web开发领域。
JavaScript:JavaScript也是一种脚本开发语言,主要运行在浏览器中,可以为网页增加动态功能。JavaScript虽然名字里有Java字样,但其实和Java没有太大关系。
除了上述几种编程语言,还有很多主流编程语言,比如C++、Python、Ruby等。近几年随着移动互联网的普及,基于苹果iOS系统所使用的Objective-C、Swift语言也发展迅速。
3.3 编程语言中的数据类型
数据类型是用来在计算机世界中区分和表达数据载体的规则,数据类型是一种对数据的约束,每一种数据都有一种且唯一一种数据类型,数据类型代表编程语言中的最基本规则。“数据”是计算机世界中的基本单元,一张图片是一个数据,一个文字也是一个数据。如下图所示,一个基本的数据单元主要由几部分构成,分别是数据类型、数据名称和数据值。数据的名称也叫变量名,每一个变量都有对应的数据值。
每一门编程语言都有自己的基础语法,就像我们学外语需要掌握语法一样。编程语言是和计算机进行沟通的语言。计算机要理解成语的意思,首先就得从数据类型开始,数据类型好比我们说话用的单词的意思,计算机需要理解我们传递了什么信息。另外就是语法结构,好比我们说的单词需要以什么样的顺序和方式被组织起来,不同的外语里有不同的语法规则,也有不同的单词,例如表示苹果这一物体,中文里叫“苹果”,但英文里叫“apple”,中文的主谓语顺序和英语中的也略有差别。同理,在编程语言中也会有不同的语法规则和不同的关键字。我们先看一下编程语言中的基本数据类型。
3.3.1 表示整数的“整型”
在产品中,我们通常会在需要计算一些数值时使用到整型,比如需要统计通讯录有多少人时,需要声明一个整型变量来记录通讯录项目总数,而且这个变量是可以持续累加进行计算的。
整型是一种数字类型,所有的不带小数点的数字都属于整型,在编程语言中,用关键词int来表示整型。关键词是编程语言中一种约定存在的表示一定具体意义的形容词,关键字一般都是固定存在的,就好比语言中的一些固定词语。在程序中,我们可以给变量取一个名字,然后声明这个变量诶整型,例如“int a=10”,这是一个基本的程序语句,里面有几个关键字符号,从左到右,首先是“int”,说明这个数据类型被我们声明为整型,也就是整数类型,然后是“a”,这是我们随便取的名字,我们还可以叫x或者y都行,再往后就是“=”,这个等号其实是赋值号,代表的意思是,将“10”的这个整数赋值给变量“a”。至此,我们就完成了一个简单地程序语句。同时,整型是可以被用来进行数学计算的,例如我们将两个整数进行加减乘除的数学计算,“int a=1;int b=2;int c=a+b”,在这条程序语句中,最终变量“c”的计算结果是“3”。
3.3.2 表示文本的“字符型”
字符型是一种文本类型,字符型的内容没有规则限制,可以是任意内容。在不同的编程语言中,表示字符型的关键字略有不同。例如在Java语言中,我们使用关键字String来表示字符型数据;在C语言中,字符型使用关键字char来表示;在Objective-C语言中用NSString表示字符型数据。字符型数据一般会用引号表示该数据属于字符型,例如“hello”就是一个字符类型的数据,表示一个单词,也可以是“hello world”,表示一句话,中间的空格也算是这个字符型数据的一部分。如果字符型数据的内容是数字,比如“1024”,这时候并不代表是整数,而就是一个字符型数据。也就是说,字符型的“1024”并不具备数学意义,不能用来做计算。
字符型的数据在我们设计产品的过程中其实使用得最多,我们在产品界面上展示的所有信息在程序里都是以字符型的数据类型展示的,例如用户登录界面上看到的用户名、密码的文字,以及输入的用户名和密码(这些内容会以字符型的数据被程序读取,然后做进一步处理)。可以说,字符型是适应最广泛的一种数据类型。
3.3.3 表示小数的“浮点型”
浮点型也是一种数字类型,与整数型相比,浮点型的数据都是带小数点的数据。在编程语言中,一般用float或者double标记浮点型数据。在产品设计中,我们会用到浮点型,例如在填写体重的时候,我们可以输入“60.5”这样的数值来表示公斤,在一些专业型的工具产品中,我们会输入一些带小数点的数来设置一些参数,这时都会使用到浮点型。当然,如前文所说,在界面上获取的其实都是字符型,只是我们在程序里面将字符型转换为了浮点型。
3.3.4 表示是非判断的“布尔型”
布尔型是一种特殊的数据类型,布尔型的数据只有两种值,即“true”和“false。“true”对应的序号是1,“false”对应的序号是0。布尔型变量的赋值只能是“true”或者“false”,一般用来做标记使用,反应现实世界里的p真假判断。在编程语言中,一般用关键字“boolean”或者“bool”表示和声明布尔型数据。
在产品设计中,我们经常会在流程设计里使用到布尔型。例如,如果用户在注册时需要同意一个注册协议,注册协议旁边往往有一个可以勾选的小框,勾上视为同意,不勾视为不同意。
在程序实现中,我们可以使用布尔型的数据对这个操作进行记录。例如,我们可以设置一个变量来记录这个操作,“boolean isSelected = false”,我们声明了一个变量名字叫做“isSelected”,然后给它初始赋值为“false”,即设定默认是没有勾选的,如果用户在注册时将勾选项选上,我们就可以将这个变量的值修改为“true”。布尔型在程序设计中使用得较多,主要用于控制流程或者做一些特殊标记。
3.3.5 数据类型间的转换
前面我们提到了编程语言中三种最常见的数据类型,分别是整型、字符型和浮点型。除了这三种基础类型外,还有一些其他类型,例如长整型、单精度浮点型和双精度浮点型,这些都是基于基础数据类型的其他数据类型,它们一起构成了程序的数据基础。前文提到的数据类型间的转换,例如我们从界面上获取的整型数据输入实际上首先得到的是字符型。这时,我们就需要将字符型转换为整型,在大部分编程语言中,都会有对应的工具来进行数据类型转换。
3.3.6数据拼接
在编程语言中,数据拼接一般是字符型数据间的拼接,拼接后的字符型数据统称为字符串,字符串的内容可以表达任何内容,字符串简单来说就是一串文本,如前文所说,“1024“是一个文本,也就是一个字符串,并不是数学意义上的1024,字符串所能表达的内容非常多,字符串的内容既可以是数字也可以是小数或者各种符号。
产品设计中,假设我们要设计一个功能展示多少人参与了活动,文本会设计成“目前有XX人参与了本次活动”,这句话在程序里是以字符型的数据类型存储的,整个字符串中间关于多少人的部分是变量,也就是说这里的数字实惠动态变化的。在编程中,我们用到数据拼接来实现,以Java语言为例,第一种是我们现将“目前有”这个字符串用变量“a”表示,将后面的“人参与了本次活动”这个字符串用变量“c”表示,中间的数字我们在程序中获取时是整型数据,先将整型转换为字符型然后用变量“b”表示。这时我们通过“String s = a + b + c”这条程序语句就可以实现字符串数据的拼接,从而实现这个功能。
在进行产品设计时,如果某个功能涉及固定字符和动态字符的组合,就要考虑数据拼接了。
3.4 编程语言中的逻辑结构
编程语言中的逻辑结构类似于我们所说的语言中的语法,是用来组织和表达语义的规则。实际上,编程就是把现实世界的状态和过程通过程序语言在计算机里写出来,然后让告诉计算机去执行。
3.4.1 条件判断“if else”
“if”和“else”在英语中的意思是“如果”和“否则”。在编程语言中,我们可以用这两个关键字来控制逻辑判断流程。举个栗子,我们需要判断用户登录时是否输入了用户名和密码,如果用户名和密码输入框为空,那我们就提示用户相关信息;如果都不为空,那我们就执行登录的操作。用编程语言中的“if else”控制可以按如下写法。
If (用户名和密码不为空) {
执行登录操作
}else{
提示用户相关信息
}
上面就是一段简单的“代码”片段,但实际上它不是真正的代码,因为真正的代码是不能用中文编写的。关于条件判断的逻辑结构,还有如下写法。
If (条件1) {
执行结果1;
}else if (条件2) {
执行结果2;
}else{
执行结果3
}
3.4.2 条件选择“switch case”
我们用自动售货机买东西,如果有5元、10元和15元的东西可供购买,那我们投入5元,就能选择5元的商品;如果投入10元或者15元,那我们可以选择10元或者15元的商品;如果投入的钱无法识别,则会退回并做相应的提示。这就是条件选择逻辑,在程序中我们可以用如下方式来表示。
switch(钱的面值)
case 5:
选购5元商品;
case 10:
选购10元商品;
case 15:
选购15元商品;
default:
退回并提示无法识别:
}
从上边的”伪代码“中可以看到“switch”后面的括号里对投入的钱的面值进行了判断。需要注意的是,在“switch case”条件选择中,条件值的数据类型必须是整型的,也就是说其他数据类型的值是不能使用的。“case”是对应输入值的条件分支,“case”对应值得数据类型也必须是整型,每一个“case”的分支都会有一个对应的执行结果,例如输入的值是5,条件选择会执行第一个“case”部分的内容,即“选购5元商品’。条件选择执行顺序从上至下,如果输入的值是15,那经过前两个“case”的条件判断后,执行第3个“case”选项的工作。若输入的值在所有的“case”中都没有匹配项,那还有一个关键字“default”表示的默认执行模块,如果所有的条件都不满足,就执行该模块的内容。
案例分析:在电商产品购物环节中,我们选择商品时往往需要选择商品的尺寸或者颜色,对尺寸和颜色的选择就对应程序中的“switch case”逻辑。
3.4.3 循环操作“while/do while”
英文单词“while”有“一段时间”的意思,在编程语言中,我们可以使用“while”实现循环的逻辑控制,循环逻辑控制是指让一个事件在某一个条件下重复发生,在循环停止前持续让这个事件发生一段时间。一个驯化的逻辑往往有循环条件,例如需要循环几次,需要满足什么条件才能进行下一次循环,以及满足什么条件时结束循环等。
在现实世界中,我们经常会遇到一些需要使用循环逻辑的场景,例如倒计时(从某个数开始倒数一直到0),在这个过程中通过编程语言实现就是使用循环逻辑。以倒计时为例,我们来看如下“代码”片段。
int i = 0;
while (i < 3){
i++;
}
以上就是一个简单的循环逻辑,首先通过关键字“while”表明这是一个循环。首先,定义一个整数型的变量i,并且为i赋值为数字0。在while后面的括号里有一个判断条件,判断i是否小于3,则执行大括号里的程序语句。在大括号里的程序语句完成了对i的值得自增,而且每次都加1.第一次循环后,i的值变成了1,第二次循环后i的值变为2,第3次循环后i的值变为3,第四次循环发生时,由于此时i的值已经是3了,并不小于3,所以while后面括号里的条件不成立,循环结束。在这个过程中,需要循环发生的时间是“i++”,根据循环控制初始状态“i=0”和循环结束状态“i<3”,循环总共发生了3次。
3.5 数据的组织方式:数据结构
数据结构是计算机存储和组织数据的一种方式,是按照一定规则进行数据组织的数据的集合。通过编程语言把产品功能的逻辑表达出来,逻辑的基本单元是数据,数据通过一定的结构呈现出来。
接下来,我们介绍几种常用的数据结构。
3.5.1 数组:统一数据类型的集合
数组是指具有相同数据类型的数据元素组成的集合。数组同样有数据类型,而且一个数组内只能同时存在一种数据类型。如果定义一个整型数组,那么数组里的元素就只能是整型数据。
数组可以指定大小,而且数组里的元素可以通过数组下标标记和获取,如下图所示。
我们定义一个整型数组,并且指定这个数组的大小是3,可以写成“int a[3]”,前面的“int”表示数组的数据类型,“a”表示这个数组的名字,也就是之前提到过得变量名,中括号表示这是一个数组,括号里面的3表示这个数组的大小是3,也就是说能存放3个数组元素。完整的写法应该是“int a[3]={1,2,3}”这句程序的意思就是我们初始化了一个名为“a”的整形数组,并且制定了数组的大小为3,且初始值分别为1、2和3三个整数。
数组中的元素可以通过下标获取,在编程语言中,数组的下标一般是从0考试,比如要取数组“a”中的第一个整数1的时候,通过“a[0]”的方式就能取到,完整的写法是“int a1=a[0]”,这里的意思是我们定义了一个变量“a1”用来存储数组“a”中的第一个元素的值,“a1”的值就是整数1.
在设计产品实现方案的时候,我们经常使用数组。例如,类似微信聊天列表一类的设计,我们在实现时首先将需要展示的数据集中存放在数组里,然后在渲染界面的时候从数组中把数据元素取出来,然后再展示到界面上。数组是在程序设计中使用比较多的一种数据结构,数组的应用范围很广,而且相对来说是一种最简单的数据结构。
3.5.2 栈:汉诺塔结构
假设我们设计一个层级页面,从页面A进入B再进入C,此时如果需要返回A的话,我们首先要先返回B,继续进行返回操作才能退回到A,这就是一种典型的栈的思路。
栈又可叫作堆栈,是一种满足一定规则的数据结构,这种规则通常叫作“后进先出”。
可以把栈理解成一种底部封口,顶部开口的容器,数据元素可以从开口进入栈,这个过程我们叫“入栈”,如果要取出栈里面的数据元素,则从开口取出在上面的数据元素,这个过程叫“出栈”。“栈”的规则和“汉诺塔”是一样的,要想把底部的数据元素拿出来就必须先把前面的数据元素全部移出去。对栈里的数据存取必须按照这种规则,即出栈的顺序与入栈的顺序相反。栈的结构如下图所示。
3.5.3 队列:排队的艺术队列和栈一样,也是一种操作受一定规则限制的数据结构。队列简单理解就是平常生活的排队。队列在结构上分为队头和队尾,只能在队头执行出队操作,在队尾执行入队操作。队列实际上就是一种符合“先进先出”规则的顺序集合,队列的结构如下图所示。
队列的这种结构在程序中可以控制控制一些事务性的操作,例如一件事务包括几个步骤,而且这几个步骤有严格的先后顺序,即必须先完成前面的步骤才能进行后面的步骤。队列可以保证一个操作的原子性和顺序性,所以在处理一些事务性的操作时常用到队列结构。
3.5.4 树:长在树上的数据
树也是一种常见的数据结构,树是按照一定规则进行数据组织的结构。树状结构上的元素往往叫做一个节点。每个树状结构都有一个“根节点”,也就是树根,从树根出发可以延伸出“枝干节点”或者叫“兄弟节点”,树状结构末端的节点我们成为“叶子节点”。下图所示是一种典型的树状结构。
树状结构可以应用在产品结构设计、权限设计及用户等级设计等场景。树状结构也是程序设计中使用比较多的一种数据结构。
【案例分析】
“设计一个用户注册的功能,用户注册分为两步,第一步是设置用户登录账户,主要由手机号和登录密码构成;第二步是完善用户个人信息,例如姓名、性别、爱好等。用户注册功能在产品设计上通过两个界面显示,第一个界面进行手机号码验证并设置登录密码,设置成功后进入第二个界面完善个人信息,个人信息中的爱好可以填多个,完成个人信息设置后提交成功即可完成注册,进入产品首页。”
上述案例,我们使用了栈结构来实现界面的跳转,从验证手机号和设置登录密码的界面进入完善个人信息的界面,再从完善个人信息界面进入产品首页,这是一个典型的栈结构。另外,我们还是用了数组结构,在完善个人信息步骤中的爱好填写一栏,我们可以填写多个爱好,爱好这一数据结构可以通过字符串数组表示,每一项爱好就是数组中的一项元素。如果产品首页是常规的底部四个模块切换的结构,类似微信底部的四个模块,那么这种组合方式就是典型的树状结构,根节点控制着四个子节点,每个子节点下还可以有很多子节点。
3.6 什么是程序
程序是按照一定的规则和顺序的任务执行过程,是一套指令集合,在软件开发中,程序由数据结构和算法组成。在计算机中,我们通过编程语言表示一段程序,“程序=数据结构+算法”我们可以说程序由数据结构和算法组成,数据结构就是我们提到过的对数据进行组织和表示的结构,算法是指我们需要完成某一件事情需要处理的步骤。
程序是一套指令集合,是我们与计算机进行沟通的工具,也就是工程师所说的代码。我们使用编程语言中的数据类型表达数据含义,使用逻辑结构表达和控制逻辑处理,通过数据结构组合和呈现数据,将一套算法用编程语言表达出来就构成了程序。
3.7 程序的最小执行单元
程序的最小执行单元我们称为函数或者方法,函数是完成一项具体任务的独立模块,函数的组成包括输入、输出及函数内部的处理流程。下面我们定义一个简单的函数,它包括输入、输出和内部处理流程。
int add (int a,int b) {
int c =a + b
return c;
}
在上面这个函数中我们给函数取了一个名字叫“add”,然后函数的返回值类型是整型,也就是在“add”前面的“int”标识。函数名后面的括号里定义了两个变量,叫做函数的参数,参数就是函数的输入值,参数也有数据类型,这里我们定义了两个整型的参数,分别为变量“a”和“b”。在大括号内部,我们定义了对这个函数的处理流程,完成了输入参数的相加动作。我们定义了一个变量“c”来存储“a+b”的值,然后使用了一个关键字“return”返回函数执行的结构。
本章总结:
4.产品经理学数据库
4.1 产品经理为什么要学数据库
什么是数据库
我们每天使用互联网产品会产生大量的数据,例如使用微信产生的很多聊天记录,在微信里发的朋友圈照片,使用百度搜索的各种内容,使用淘宝进行购物的记录等,这些数据都存储在数据库中。
数据库运行在服务器中,类似于一个进行数据存储的仓库,数据按照一定的规则存储,可以对数据库中国的数据进行增删改查的操作。
我们可以定义数据库的存储格式,例如我们需要存储微信朋友圈的内容,朋友圈的内容包括发送者是谁、图片、文字和时间,这些内容格式定义好以后,我们就可以将这些存储格式告诉数据库,之后往数据库里存储的内容就按照这个格式存储。对数据库的操作不仅仅是往里面存东西,还可以根据不同的需求从数据库里读取内容。同时,我们还可以对数据库里的内容进行修改。数据库使我们对数据进行集中管理的仓库,它通常包括增、删、改、查这四个基本操作。数据库是互联网的重要组成部分,没有数据库,我们的数据就无法存储,就无法体验到如今内容丰富的互联网。
目前数据库的类型主要是两种,关系型数据库和非关系型数据库。关系型数据库是一种应用比较广泛的数据库,很多产品和系统的后台数据库都是用关系型数据库,例如银行的交易系统和电商的商品管理系统,前文提到的MySQL就是关系型数据库的代表。非关系型数据库相对于关系型数据库来说,主要在存储格式和设计思想上存在差异。
4.2 关系型数据库
关系型数据库是一种基于关系模型的数据库,关系模型折射现实世界中的实体关系,将现实世界中各个实体及实体之间的关系通过关系模型表达出来。例如,人是一个实体,人与人之间有关系,这种实体和关系间的对应就可以表达为一个关系模型。
现实世界中我们可以定义很多实体,一个人是一个实体,一辆车、一栋房子都可以表达成一个实体。实体是一系列属性的集合,人作为一个实体有姓名、年龄、性别等基本属性,人还可以有职业、爱好等附加属性,这些属性的集合构成人这个实体。与此同时,一个属性也可以单独成为一个实体。例如,性别就可以成为一个单独的实体,这个实体里面的属性包括两种,男和女。
在人这个实体和性别这个实体之间存在一个关系,一个人只能有一种性别,所以人和性别这两个实体之间的关系是一对一的。职业也可以构成一个实体,职业的属性包括工程师、建筑师、画家等很多种,人作为实体与职业这个实体的关系是一对多的,也就是说一个人可以拥有多个职业,是建筑师的同时也可能是画家(笔者注:现在这种拥有多重职业的人喜欢叫自己斜杠青年)。将这种现实世界中的实体和关系通过关系模型表达出来就可以形成一种数据存储关系,通过这种方式表达的数据库就叫做关系型数据库。两个实体关系之间的联系如下图所示。
实体A具有三个属性,实体B具有三个属性,他们之间以某一种关系关联起来,这种关系可以是一对一的,也可以是一对多或者多对多的。通过这种实体关系模型我们就可以将现实世界中的实物表示成数据存储模型。关系型数据库是目前应用比较多的一种数据库模型,主流的关系型数据库有之前提到的MySQL,另外还有Oracle、DB2等,在智能手机中使用的小型轻量级数据库SQLite也是关系型数据库的一种。
对产品经理来说,在产品设计阶段不需要考虑技术实现选用哪种数据库,这是架构师在进行技术选型时考虑的问题,但在设计产品角色和逻辑关系时,产品经理需要明白产品背后的数据库是如何设计的。例如电商产品,如果使用关系型数据库,势必有一个数据实体是专门用来存储商品数据的,而且电商类产品有订单,订单在数据库中也是以一个实体的形式存在,商品和订单这两个实体之间又存在一个关联关系,一个订单可以包含多个商品,一个商品也可以出现在多个订单中,所以订单实体和商品实体之间是多对多的关系。
4.2.1 数据库表和表的关系
前面提到了关系型数据库中的实体关系模型。在关系型数据库中可以通过数据库表和表之间的关系来具象表示这种模型,表就是我们常用的二维表格,有表的名字,表的各项标题名。例如对人这个实体,我们可以建立一个表,表的名字可以取名为“people”,在表中可以存在属性,例如姓名、性别、年龄、职业、爱好等。对于职业我们可以新建另一个表,取名为“profession”,表中的属性可以表示为职业名称。需要注意的是,在数据库中,表明和属性名只能用英文命名。表与表之间可以通过关系来链接,如果两个表之间有对应关系,在两个表中就有对应的属性项来表示这个关系。我们来看一下人和职业这两个表及表之间的关系,如下图所示。
这两个数据库表对应人这个实体的表叫做“people”,对应职业这个实体的表叫做“profession”,这两个表都预设了一些属性,我们为这些属性取了对应的名字。在“people”表中第一个属性的名字叫做“peopleId”,这是一个唯一标识,在数据库表中成为“主键”,标识在数据库表中的一条唯一数据,理论上每一个数据库表的属性里面都有一个用来做唯一性标记的id,这里我们使用“peopleId”来唯一标记一个人,即每个人只会在该表中出现一次。对应在职业表“profession”中,我们也使用了一个叫“professionId”的属性名标识唯一性。在“people”表中有一个标识职业的属性叫做“profession”,通过这个属性可以喝“profession”表产生关联,可以将所有的职业信息全部存储在“profession”表中,然后在“people”表中通过“profession”属性和“profession”表进行关联。下面来介绍数据库表之间如何通过字段进行关联。
4.2.2 数据库字段和字段类型
在关系型数据库中,我们使用二维表来表示关系模型,在二维表中可以使用属性来表示某一类数据,属性在数据库表中也成为字段。一个数据库表有表名,也有字段名,理论上说,一个数据库表可以有无限个字段,每一个字段名都不重复,且表名和字段名都只能用英文表示。
与编程语言中的数据类型一样,数据库表中的字段同样也有字段类型,在编程语言一章中我们提到常用的数据类型有表示整数的整型,也有表示字符的字符型。在数据库表中,每一个字段也有自己的数据类型,例如在”people”这个表中,用于表示姓名的字段“name”可以定义为字符型,用来表示年龄的字段可以定义为整型。
为了更简洁而且分类更加明确地表达数据库表,我们可以通过关联关系将不同的实体进行连接,例如前问我们与人相关的职业单独定义成一个实体,在“profession”表中我们可以为每一个职业分配一个“id”,也就是主键,然后在“people”表中通过关联对应的“id”实现实体间的关联,如下图所示。
我们在【4.2.1 数据库表和表的关系】中配图的基础上添加了每一个字段的数据类型,然后将“people”表中的“profession”字段与“profession”表中的“professionId”字段关联起来。通过这种关联,两个表就产生了一个关联,接下来我们看具体的数据如何在数据库表里进行存储,以及关联关系是如何表示的,如下图所示:
典型的关系型数据库表结构实际上就是一个二维表,我们通过“peopleId”来唯一标识一个具体的人,然后存储了包括姓名、性别、年龄和职业等信息。职业信息我们使用了另一个表来存储,然后通过关联两个表的对应字段进行联系。可以看到在“people”表中的字段“profession”我们存储的数据是整型数据1,对应在“profession”表中也有一个整形字段“professionId”,对应值是1,而且代表的职业名称是“professionName”对应的建筑师,从中可知张三的职业是建筑师。我们可以单独维护一个职业信息表,如果有新增的职业只需往“profession”表中添加数据,在“people”表中通过引用“profession”表的字段来表示职业。
数据库表字段的确定和表关系的设计在设计数据库初期就需要确定,设计一个完整且兼容性强的数据库需要非常丰富的经验及对产品需求的充分理解。
4.2.3 数据库操作语言(SQL)
SQL(Structured Query Language)即结构化查询语言,是一种用来操作关系型数据库的编程语言,可以理解为对数据库的操作命令。我们可以使用SQL对数据库进行各种操作,包括创建数据库表,为某一个数据库表添加数据,或者对数据进行修改、删除及查询操作等。SQL和编程语言一样,也有固定的语法结构,我们可以用对应的语句对数据库进行操作。下图所示是数据库操作员通过SQL语句操作数据库然后获取操作结果的流程图。
4.3 非关系型数据库
与关系型数据库相比,非关系型数据库是一种相对松散且可以不按照严格的结构规范进行存储的数据库。非关系型数据库一般叫做NoSQL(Not Only SQL),非关系型数据库没有关系型数据库那样严格的数据结构约束,在存储的形式和使用上有别于关系型数据库。现在主流的非关系型数据库有MongoDB和CouchDB。以MongoDB为例,它的数据以类似文档的方式进行存储,每一个文档都有对应的唯一标识和版本号。
在关系型数据库中,我们使用二维表和字段来规范数据存储,但在非关系型数据库中,我们可以按照更灵活的方式定义数据存储。在非关系型数据库MongoDB中,我们可以使用键值对的方式表示和存储数据,键值对就是“key-value”的形式,类似在关系型数据库表中的字段名和该字段名对应的值。在MongoDB中,使用JSON格式的数据进行数据表示和存储,例如我们表示“people”这一数据结构可以使用如下方式。
{
“peopleId”: “001”
“name”: “张三”
“sex”: “男
“age”: “28”
“profession”: “建筑师"
}
上述就是一种JSON结构,一共有5个数据在这个JSON结构中,它们以“key-value”的形式存储,冒号左边的是“key”,冒号右边的是“value”,基于这个结构我们可以无限扩展其他的键值对,而且键值对可以进行嵌套,例如下面这种结构。
{
“peopleId”: “001”
“name”: “张三”
“sex”: “男
“age”: “28”
“profession”: “id”:{“1”,“professionName”:“建筑师”}
}
在上面这种结构中,键“profession”对应的值也是一个JSON结构,通过这种嵌套的方式可以很灵活地扩展数据表示,数据存储方式也更灵活。
非关系型数据库适用场景:一些对存取要求比较高并且并发处理比较高的场合,例如对网站访问数据的统计。
非关系型数据库处在不断发展的过程中,现阶段与关系型数据库形成一种互补的局势,在很多产品后台,同时使用关系型数据库和非关系型数据库。
本章总结: