关系型数据库设计:三大范式的通俗理解

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

而通常我们用的最多的就是第一范式(1NF)、第二范式(2NF)、第三范式(3NF),也就是本文要讲的“三大范式”。

第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。

举例说明:

在上面的表中,“家庭信息”和“学校信息”列均不满足原子性的要求,故不满足第一范式,调整如下:

可见,调整后的每一列都是不可再分的,因此满足第一范式(1NF);

 

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

举例说明:

在上图所示的情况中,同一个订单中可能包含不同的产品,因此主键必须是“订单号”和“产品号”联合组成,

但可以发现,产品数量、产品折扣、产品价格与“订单号”和“产品号”都相关,但是订单金额和订单时间仅与“订单号”相关,与“产品号”无关,

这样就不满足第二范式的要求,调整如下,需分成两个表:

   

 

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

举例说明:

上表中,所有属性都完全依赖于学号,所以满足第二范式,但是“班主任性别”和“班主任年龄”直接依赖的是“班主任姓名”,

而不是主键“学号”,所以需做如下调整:

  

这样以来,就满足了第三范式的要求。

ps:如果把上表中的班主任姓名改成班主任教工号可能更确切,更符合实际情况,不过只要能理解就行。

 

[GIT] git中fetch和pull的区别

git中都fetch命令是将远程分支的最新内容拉到了本地,但是fetch后是看不到变化的,在tortoiseGit中使用switch/checkout查看当前分支,发现此时后本地多了一个FETCH_HEAD的指针,checkout到该指针后可以查看远程分支的最新内容。然后checkout到master分支,执行metch,选中FETCH_HEAD指针,合并后如果出现冲突则解决冲突,最后commit。

pull的作用就相当于fetch和merge,自动合并:

git fetch origin master
git merge FETCH_HEAD

然后需要手动解决冲突,并commit。


分支的概念:
分支是用来标记特定代码的提交,每一个分支通过SHA1sum值来标识,所以对分支的操作是轻量级的,你改变的仅仅是SHA1sum值。

如下图所示,当前有2个分支,A,C,E属于master分支,而A,B,D,F属于dev分支。

A----C----E(master)
 \
  B---D---F(dev)

它们的head指针分别指向E和F,对上述做如下操作:

git checkout master
git merge dev

之后的情形是这样的:

A---C---E---G(master)
 \         /
  B---D---F(dev)

现在A,B,C,D,E,F,G属于master,G是一次合并后的结果,是将E和F的代码合并后的结果,可能会出现冲突。而A,B,D,F依然属于dev分支。可以继续在dev的分支上进行开发:

A---C---E---G---H(master)
 \         /
  B---D---F---I(dev)

理解gitfetch,关键是理解FETCH_HEADFETCH_HEAD指的是:某个branch在服务器上的最新状态。

一般来说,存在2种情况:

如果没有显示地指定远程分支,则远程分支的master将作为默认的FETCH_HEAD。
如:git fetch origin或者git fetch origin master

如果指定了远程分支,则将这个远程分支作为FETCG_HEAD
如:git fetch origin dev设定当前分支的FETCG_HEAD为远程服务器的dev分支。它就相当于git pull origin dev的第一步,并不会在本地创建新的分支。另外git fetch origin dev这个命令可以用来测试远程分支dev是否存在。

git fetch origin dev :branch1

上面这个命令的执行过程如下

  1. 首先执行上面的fetch操作
  2. 使用远程dev分支在本地创建branch1分支(但不会切换到该分支)
  3. 如果本地不存在branch1分支,则会自动创建一个新的branch1分支,如果存在branch1分支,并且是fast forward,则会自动合并这2个分支,否则会阻止以上的操作。

Mysql 工具集

1. 查询所有的表名

select column_name from information_schema.columns where table_schema='your schema' and table_name='table name'

2. dump/restore

mysql -uroot -h -p -P3306   < tbike.sql;
mysqldump -h -P3306 -uroot -p  > tbike.sql;

3.修改blob的大小

mysql根据配置文件会限制server接受的数据包大小。
有时候大的插入和更新会被max_allowed_packet 参数限制掉,导致失败。
查看目前配置  
show VARIABLES like '%max_allowed_packet%';
显示的结果为:
 
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+

谈谈我的博世hackathon感受

一年一度的博世黑客马拉松要开始了,极客圈的小伙伴们都在跃跃欲试。好些个朋友都来问我这个参加过的选手,诸如xdk是啥啊,容易上手吗等问题,我干脆写到我自己的技术日记,要看随取。这里的确要吐槽下博世,的确宣传力度和技术社区培养不够,资料的确难找,不像STM32啊,Arduino啥的开源智能硬件,有强大的社区支持,例程和开发人员非常多。这也让xdk这个好东西让极客们有些陌生感。

粗暴的说,XDK是博世推出的IoT平台开发套件,它包含一个高度集成化的硬件终端,一些中间件,IDE和云平台。XDK秉承德国人一贯的严谨性,慢工出细活,东西是真TMD的精致,耐操。为啥这么说呢,大家都来IoT领域布局,所以都得有自己的独门绝技吧,比如,阿里拿手活儿是云计算,腾讯么靠强大的社交能力,这不Robin Li 要转型,祭出哥要扛起AI大旗杀手锏,结果一瓶矿泉水披头而下。那么德国博世的杀手锏则是传感器,传感器,传感器!

这个小盒子就是xdk的终端设备,它不是原型,它是一个实实在在的产品,而且是工业级的!工业级什么概念呢,自行百度吧。按产品设计的苛责级别是这样的:军工级别>车规级别>工业级别>消费电子级别。哥也参加过不少类似编程活动,现场给各种传感器模块,都是几块到几十块钱的廉价传感器,什么光敏电阻光传感器,PIR人体传感器,温湿度等等,我觉得和这个比起来呢,就是小孩玩具与成人级电子产品的差距,那些只能拿来玩一下丢掉,就是一个字,飘….。这个小盒子里集成了微机电加速度计,磁力计,陀螺仪,以及温湿度,压力,声光的传感器,还有2.4G蓝牙和WIFI互联方案,天线,卡槽和锂离子电池。这些都在一个指甲盖大小的电路板上集成!我比赛那会儿问专家,这么小,那诸如温度传感器自身的热量导致的数据准确怎么保证呢?专家说,我们有专门的补偿算法,可以直接用。请收下我的膝盖,瑟瑟发抖。这玩意儿除了贵,没其他毛病。我估计这个设备要卖一到两千元,因为它是面向工业级的。随贴随用,低功耗。

另外我简单看了下,板子上跑的应该是FreeRTOS,USB上电后,自动识别设备,直接可以和PC上的开发套件通信。PC的开发套件呢,其实就是基于eclipse CDT做的插件开发,细心的德国人几乎把你能想到的用户需求都给你做了,开发套件里面集成好了交叉编译链,烧写和调试等工具,而且包含大量的例程,每种外设都有例程,现场编程基本只需要把例程代码给copy出来通过编译,然后简单配置下外设即可一键烧写,开始调试,寄存器watch,断点等等,十分方便。这里截几个图给大家体验下。

开发时,你的数据总得上云啦。去年呢,博世时选择了物联网供应商sigfox,sigfox会发给你一个基于Arduino的EV板,然后给你提供了一个USB doogle的模拟基站,把Arduino和xdk板随便找几个rxtx杜邦线一戳,数据就来了,Arduino随便把示例程序改一下,烧一下,就可以和USB doogle的模拟基站通信了。PC上的模拟基站呢,其实很简单,用nodejs写的一个中转程序,通过浏览器配置好后,数据自动会被模拟基站利用PC的网络以HTTP方式发送出去。你只要配置发送目标例如:http://youip:port/youapi?name=$0&….$1..$2,用占位符就把数据传出去了。一次http get请求可以传152字节(记不太准确了)。今年好像没用这个了,这让你发挥空间更大,请极客们自行携带你的爱板,随便玩。

至于云端嘛,博世的云端时和微软Azure合作的,部署在微软云上,叫Bosch IoT Suite,这个其实你可以用可以不用,如果你对服务器熟悉,你完全可以随便把你自己的阿里云,腾讯云啥的http服务搞一个在那里,写几行php啊,nodejs或者servlet就行了。坦白讲,微软云的东西吧,用户接口很不好,不符合中国人的使用习惯,资源入口很难找,中文网站像机器翻译的一样。

我觉得博世的赛题也挺好的,可以充分发挥其传感器的作用。这里给小伙伴们点建议,比如电梯场景,可以利用加速度计检测电梯的运行速度,因为电梯可以调节运行加速度,商场等场所就很快,住宅楼则慢很多,可以用陀螺仪检测意外的轿厢抖动,还有可以利用光线传感器检测开门关门次数啊啥的,再检测些温湿度等工作环境啥啥。随便组合一下,做个电梯运行健康估值啊,异常情况预警啊,老化预测啊等等。我保证你带1万奖金回家。哈哈。。。。

(XDK_Getting_Started_v2 附上一份getting started指南,拿走不谢)

 

 

Python时间函数

在用Python编写程序时经常会遇到需要求解一个函数运行时间的情况,发现一个利用Python语言特性编写的比较巧妙的计算方法,这里记录和大家分享一下:

def time_function(f, *args):
    """
    Call a function f with args and return the time (in seconds) that 
    it took to execute.
    """
    import time
    tic = time.time()
    f(*args)
    toc = time.time()
    return toc - tic