精华内容
下载资源
问答
  • 电商网站数据库常见结构设计

    千次阅读 2019-04-03 20:11:02
    商品列表页(loading) 事件名称:loading 标签 含义 ... 动作:开始加载=1,加载成功=2,加载失败=3 ... 加载时长:计算下拉开始到接口返回数据的时间,(开始加载报0,加载成功或加载失败才上报...

    商品列表页(loading)

    事件名称:loading

    标签

    含义

    action

    动作:开始加载=1,加载成功=2,加载失败=3

    loading_time

    加载时长:计算下拉开始到接口返回数据的时间,(开始加载报0,加载成功或加载失败才上报时间)

    loading_way

    加载类型:1-读取缓存,2-从接口拉新数据
    (加载成功才上报加载类型)

    extend1

    扩展字段 Extend1

    extend2

    扩展字段 Extend2

    type

    加载类型:自动加载=1,用户下拽加载=2,底部加载=3(底部条触发点击底部提示条/点击返回顶部加载)

    type1

    加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败)

     

     

    商品点击(display) 

    事件标签:display

    标签

    含义

    action

    动作:曝光商品=1,点击商品=2

    goodsid

    商品ID(服务端下发的ID

    place

    顺序(第几条商品,第一条为0,第二条为1,如此类推)

    extend1

    曝光类型:1 - 首次曝光 2-重复曝光(没有使用)

    category

    分类ID(服务端定义的分类ID

    商品详情页(newsdetail)

    事件标签:newsdetail

    标签

    含义

    entry

    页面入口来源:应用首页=1push=2、详情页相关推荐=3

    action

    动作:开始加载=1,加载成功=2pv),加载失败=3, 退出页面=4

    goodsid

    商品ID(服务端下发的ID

    show_style

    商品样式:0、无图、1、一张大图、2、两张图、3、三张小图、4、一张小图、5、一张大图两张小图

    news_staytime

    页面停留时长:从商品开始加载时开始计算,到用户关闭页面所用的时间。若中途用跳转到其它页面了,则暂停计时,待回到详情页时恢复计时。或中途划出的时间超过10分钟,则本次计时作废,不上报本次数据。如未加载成功退出,则报空。

    loading_time

    加载时长:计算页面开始加载到接口返回数据的时间 (开始加载报0,加载成功或加载失败才上报时间)

    type1

    加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败)

    category

    分类ID(服务端定义的分类ID

    广告(ad)

    事件名称:ad

    标签

    含义

    entry

    入口:商品列表页=1  应用首页=2 商品详情页=3

    action

    动作:请求广告=1 取缓存广告=2  广告位展示=3 广告展示=4 广告点击=5 

    content

    状态:成功=1  失败=2  

    detail

    失败码(没有则上报空)

    source

    广告来源:admob=1 facebook=2  ADX(百度)=3 VK(俄罗斯)=4

    behavior

    用户行为:
    主动获取广告=1  
    被动获取广告=2

    newstype

    Type: 1- 图文 2-图集 3-段子 4-GIF 5-视频 6-调查 7-纯文 8-视频+图文  9-GIF+图文  0-其他

    show_style

    内容样式:无图(纯文字)=6 一张大图=1  三站小图+=4 一张小图=2 一张大图两张小图+=3 图集+ = 5 
    一张大图+=11   GIF大图+=12  视频(大图)+ = 13
    来源于详情页相关推荐的商品,上报样式都为0(因为都是左文右图)

    消息通知(notification)

    事件标签:notification

    标签

    含义

    action

    动作:通知产生=1,通知弹出=2,通知点击=3,常驻通知展示(不重复上报,一天之内只报一次)=4

    type

    通知id:预警通知=1,天气预报(早=2,晚=3),常驻=4

    ap_time

    客户端弹出时间

    content

    备用字段

     

    用户前台活跃(active_foreground)

    事件标签: active_foreground

    标签

    含义

    push_id

    推送的消息的id,如果不是从推送消息打开,传空

    access

    1.push 2.icon 3.其他

    用户后台活跃(active_background)

    事件标签: active_background

    标签

    含义

    active_source

    1=upgrade,2=download(下载),3=plugin_upgrade

    评论(comment)

    描述:评论表

    序号

    字段名称

    字段描述

    字段类型

    长度

    允许空

    缺省值

    1

    comment_id

    评论表

    int

    10,0

     

     

    2

    userid

    用户id

    int

    10,0

    0

    3

    p_comment_id

    父级评论id(为0则是一级评论,不为0则是回复)

    int

    10,0

     

    4

    content

    评论内容

    string

    1000

     

    5

    addtime

    创建时间

    string

     

     

    6

    other_id

    评论的相关id

    int

    10,0

     

    7

    praise_count

    点赞数量

    int

    10,0

    0

    8

    reply_count

    回复数量

    int

    10,0

    0

    收藏(favorites)

    描述:收藏

    序号

    字段名称

    字段描述

    字段类型

    长度

    允许空

    缺省值

    1

    id

    主键

    int

    10,0

     

     

    2

    course_id

    商品id

    int

    10,0

    0

    3

    userid

    用户ID

    int

    10,0

    0

    4

    add_time

    创建时间

    string

     

     

    点赞(praise)

    描述:所有的点赞表

    序号

    字段名称

    字段描述

    字段类型

    长度

    允许空

    缺省值

    1

    id

    主键id

    int

    10,0

     

     

    2

    userid

    用户id

    int

    10,0

     

    3

    target_id

    点赞的对象id

    int

    10,0

     

    4

    type

    点赞类型 1问答点赞 2问答评论点赞 3 文章点赞数4 评论点赞

    int

    10,0

     

    5

    add_time

    添加时间

    string

     

     

    错误日    

    errorBrief

    错误摘要

    errorDetail

    错误详情

    展开全文
  • Linux 目录结构

    千次阅读 2016-09-12 11:35:24
    目录说明目录结构Linux 和 Windows 的最大不同之处在于目录结构设计。进入 Windows 系统,打开 C 盘,你会发现一些常见的文件夹;而进入 Linux 后,执行 ls -l / 会发现在“/”(根目录)下包

    简述

    对于每一个学习 Linux 的人来说,了解 Linux 文件系统的目录结构至关重要。想要熟练使用 Linux,让 Linux 听命于自己,就必须掌握这些目录。

    | 版权声明:一去、二三里,未经博主允许不得转载。

    目录结构

    Linux 和 Windows 的最大不同之处在于目录结构的设计。进入 Windows 系统,打开 C 盘,你会发现一些常见的文件夹;而进入 Linux 后,执行 ls -l / 会发现在“/”(根目录)下包含很多的目录,比如 etc、usr、var、bin 等目录,进入其中一个目录后,看到的还是很多的文件和目录。

    这里写图片描述

    Linux 的目录结构类似于树形结构,如下所示:

    这里写图片描述

    要认识 Linux 的目录结构,首先要认识目录结构最顶层的“/”,任何目录、文件和设备等都在此目录下。Linux 的文路径与 Windows 不同,Linux 的文件路径类似于“/home/wang”,Linux 没有 Windows中“盘符”的概念。

    目录说明

    常见的主要目录:

    目录 说明
    / 根目录。文件的最顶端,/etc、/bin、/dev、/lib、/sbin 应该和根目录放置在一个分区中,而类似/usr/local 可以单独位于另一个分区
    /bin 存放系统所需要的重要命令,比如文件或目录操作的命令 ls、cp、mkdir 等。另外 /usr/bin 下也存放了一些系统命令,这些命令对应的文件都是可执行的,普通用户可以使用大部分命令
    /boot 存放 Linux 启动时内核及引导系统程序所需要的核心文件,内核文件和 grub 系统引导管理器都位于此目录
    /dev 存放 Linux 系统下的设备文件,如光驱、磁盘等。访问该目录下某个文件相当于访问某个硬件设备,常用的是挂载光驱
    /etc 一般存放系统的配置文件,作为一些软件启动时默认配置文件读取的目录,如 /etc/fstab 存放系统分区信息
    /home 系统默认的用户主目录。如果添加用户时不指定用户的主目录,默认在 /home 下创建与用户名同名的文件夹。代码中可以用 HOME 环境变量表示当前用户的主目录
    /lib 64 位系统有 /lib64 文件夹,主要存放动态链接库。类似的目录有 /usr/lib、/usr/local/lib 等
    /lost+found 存放一些系统意外崩溃或及其意外关机时产生的文件碎片
    /mnt 用于存放挂在储存设备的挂载目录,如光驱等
    /proc 存放操作系统运行时的信息,如进程信息、内核信息、网络信息等。此目录的内容存在于内存中,实际不占用磁盘空间,如 /proc/cpuinfo 存放 CPU 的相关信息
    /root Linux 超级权限用户 root 的主目录
    /sbin 存放一些系统管理的命令,一般只能由超级权限用户 root 执行。大多数命令普通用户一般无权执行,类似 /sbin/ifconfig,普通用户使用绝对路径也可执行,用于查看当前系统的网络配置。类似的目录有 /usr/sbin、/usr/local/sbin
    /tmp 临时文件目录,任何人都可以访问。系统软件或用户运行程序(如 MySQL)时产生的临时文件存放到这里。此目录数据需要定时清除。重要数据不可放置在此目录下,此目录空间不宜过小
    /usr 应用程序存放目录,如命令、帮助文件等。安装 Linux 软件包时默认安装到 /usr/local 目录下。比如 /usr/share/fonts 存放系统字体,/usr/share/bin 存放帮助文档,/usr/include 存放软件的头文件等。/usr/local 目录建议单独分区并设置较大的磁盘空间
    /var 此目录的内容经常是变动的,如 /var/log 用于存放系统日志、/var/lib 用于存放系统库文件等
    /sys 目录与 /proc 类似,是一个虚拟的文件系统,主要记录与系统核心相关的信息,如当前系统已经载入的模块信息等。此目录实际不占硬盘容量
    /media Linux 系统会自动识别一些设备,如 U 盘、光驱等,当识别后,Linux 会把识别的设备挂载到这个目录下
    /srv 该目录存放一些服务启动之后需要提取的数据

    注意:各个发行版由不同的公司开发,所以各个发行版之间的目录可能会有所不同。Linux 各个发行版本之间目录的差距比较小,不同的地方主要是提供的图形界面及操作习惯等。

    展开全文
  • 数据库设计常见结构设计技巧

    万次阅读 多人点赞 2009-06-04 22:28:00
    一、树型关系的数据表不少程序员在进行数据库设计的时候都遇到过树型关系的数据,例如常见的类别表,即一个大类,下面有若干个子类,某些子类又有子类这样的情况。当类别不确定,用户希望可以在任意类别下添加新的...

    一、树型关系的数据表

    不少程序员在进行数据库设计的时候都遇到过树型关系的数据,例如常见的类别表,即一个大类,下面有若干个子类,某些子类又有子类这样的情况。当类别不确定,用户希望可以在任意类别下添加新的子类,或者删除某个类别和其下的所有子类,而且预计以后其数量会逐步增长,此时我们就会考虑用一个数据表来保存这些数据。按照教科书上的教导,第二类程序员大概会设计出类似这样的数据表结构:

    类别表_1(Type_table_1)

    名称 类型 约束条件 说明
    type_id int 无重复 类别标识,主键
    type_name char(50) 不允许为空 类型名称,不允许重复
    type_father int 不允许为空 该类别的父类别标识,如果是顶节点的话设定为某个唯一值

    这样的设计短小精悍,完全满足3NF,而且可以满足用户的所有要求。是不是这样就行呢?答案是NO!Why?

    我们来估计一下用户希望如何罗列出这个表的数据的。对用户而言,他当然期望按他所设定的层次关系一次罗列出所有的类别,例如这样:
    总类别
      类别1
        类别1.1
          类别1.1.1
        类别1.2
      类别2
        类别2.1
      类别3
        类别3.1
        类别3.2
      ……

    看看为了实现这样的列表显示(树的先序遍历),要对上面的表进行多少次检索?注意,尽管类别1.1.1可能是在类别3.2之后添加的记录,答案仍然是N次。这样的效率对于少量的数据没什么影响,但是日后类型扩充到数十条甚至上百条记录后,单单列一次类型就要检索数十次该表,整个程序的运行效率就不敢恭维了。或许第二类程序员会说,那我再建一个临时数组或临时表,专门保存类型表的先序遍历结果,这样只在第一次运行时检索数十次,再次罗列所有的类型关系时就直接读那个临时数组或临时表就行了。其实,用不着再去分配一块新的内存来保存这些数据,只要对数据表进行一定的扩充,再对添加类型的数量进行一下约束就行了,要完成上面的列表只需一次检索就行了。下面是扩充后的数据表结构:

    类别表_2(Type_table_2)

    名称 类型 约束条件 说明
    type_id int 无重复 类别标识,主键
    type_name char(50) 不允许为空 类型名称,不允许重复
    type_father int 不允许为空 该类别的父类别标识,如果是顶节点的话设定为某个唯一值
    type_layer char(6) 限定3层,初始值为000000 类别的先序遍历,主要为减少检索数据库的次数

    按照这样的表结构,我们来看看上面例子记录在表中的数据是怎样的:

    type_id type_name type_father type_layer
    1 总类别 0 000000
    2 类别1 1 010000
    3 类别1.1 2 010100
    4 类别1.2 2 010200
    5 类别2 1 020000
    6 类别2.1 5 020100
    7 类别3 1 030000
    8 类别3.1 7 030100
    9 类别3.2 7 030200
    10 类别1.1.1 3 010101
    ……

    现在按type_layer的大小来检索一下:SELECT * FROM Type_table_2 ORDER BY type_layer

    列出记录集如下:

    type_id type_name type_father type_layer
    1 总类别 0 000000
    2 类别1 1 010000
    3 类别1.1 2 010100
    10 类别1.1.1 3 010101
    4 类别1.2 2 010200
    5 类别2 1 020000
    6 类别2.1 5 020100
    7 类别3 1 030000
    8 类别3.1 7 030100
    9 类别3.2 7 030200
    ……

    现在列出的记录顺序正好是先序遍历的结果。在控制显示类别的层次时,只要对type_layer字段中的数值进行判断,每2位一组,如大于0则向右移2个空格。当然,我这个例子中设定的限制条件是最多3层,每层最多可设99个子类别,只要按用户的需求情况修改一下type_layer的长度和位数,即可更改限制层数和子类别数。其实,上面的设计不单单只在类别表中用到,网上某些可按树型列表显示的论坛程序大多采用类似的设计。

    或许有人认为,Type_table_2中的type_father字段是冗余数据,可以除去。如果这样,在插入、删除某个类别的时候,就得对type_layer 的内容进行比较繁琐的判定,所以我并没有消去type_father字段,这也正符合数据库设计中适当保留冗余数据的来降低程序复杂度的原则,后面我会举一个故意增加数据冗余的案例。

    二、商品信息表的设计

    假设你是一家百货公司电脑部的开发人员,某天老板要求你为公司开发一套网上电子商务平台,该百货公司有数千种商品出售,不过目前仅打算先在网上销售数十种方便运输的商品,当然,以后可能会陆续在该电子商务平台上增加新的商品出售。现在开始进行该平台数据库的商品信息表的设计。每种出售的商品都会有相同的属性,如商品编号,商品名称,商品所属类别,相关信息,供货厂商,内含件数,库存,进货价,销售价,优惠价。你很快就设计出4个表:商品类型表(Wares_type),供货厂商表(Wares_provider),商品信息表(Wares_info):

    商品类型表(Wares_type)

    名称 类型 约束条件 说明
    type_id int 无重复 类别标识,主键
    type_name char(50) 不允许为空 类型名称,不允许重复
    type_father int 不允许为空 该类别的父类别标识,如果是顶节点的话设定为某个唯一值
    type_layer char(6) 限定3层,初始值为000000 类别的先序遍历,主要为减少检索数据库的次数

    供货厂商表(Wares_provider)

    名称 类型 约束条件 说明
    provider_id int 无重复 供货商标识,主键
    provider_name char(100) 不允许为空 供货商名称

    商品信息表(Wares_info)

    名称 类型 约束条件 说明
    wares_id int 无重复 商品标识,主键
    wares_name char(100) 不允许为空 商品名称
    wares_type int 不允许为空 商品类型标识,和Wares_type.type_id关联
    wares_info char(200) 允许为空 相关信息
    provider int 不允许为空 供货厂商标识,和Wares_provider.provider_id关联
    setnum int 初始值为1 内含件数,默认为1
    stock int 初始值为0 库存,默认为0
    buy_price money 不允许为空 进货价
    sell_price money 不允许为空 销售价
    discount money 不允许为空 优惠价

    你拿着这3个表给老板检查,老板希望能够再添加一个商品图片的字段,不过只有一部分商品有图片。OK,你在商品信息表(Wares_info)中增加了一个haspic的BOOL型字段,然后再建了一个新表——商品图片表(Wares_pic):

    商品图片表(Wares_pic)

    名称 类型 约束条件 说明
    pic_id int 无重复 商品图片标识,主键
    wares_id int 不允许为空 所属商品标识,和Wares_info.wares_id关联
    pic_address char(200) 不允许为空 图片存放路径

    程序开发完成后,完全满足老板目前的要求,于是正式启用。一段时间后,老板打算在这套平台上推出新的商品销售,其中,某类商品全部都需添加“长度”的属性。第一轮折腾来了……当然,你按照添加商品图片表的老方法,在商品信息表(Wares_info)中增加了一个haslength的BOOL型字段,又建了一个新表——商品长度表(Wares_length):

    商品长度表(Wares_length)

    名称 类型 约束条件 说明
    length_id int 无重复 商品图片标识,主键
    wares_id int 不允许为空 所属商品标识,和Wares_info.wares_id关联
    length char(20) 不允许为空 商品长度说明

    刚刚改完没多久,老板又打算上一批新的商品,这次某类商品全部需要添加“宽度”的属性。你咬了咬牙,又照方抓药,添加了商品宽度表(Wares_width)。又过了一段时间,老板新上的商品中有一些需要添加“高度”的属性,你是不是开始觉得你所设计的数据库按照这种方式增长下去,很快就能变成一个迷宫呢?那么,有没有什么办法遏制这种不可预见性,但却类似重复的数据库膨胀呢?我在阅读《敏捷软件开发:原则、模式与实践》中发现作者举过类似的例子:7.3 “Copy”程序。其中,我非常赞同敏捷软件开发这个观点:在最初几乎不进行预先设计,但是一旦需求发生变化,此时作为一名追求卓越的程序员,应该从头审查整个架构设计,在此次修改中设计出能够满足日后类似修改的系统架构。下面是我在需要添加“长度”的属性时所提供的修改方案:

    去掉商品信息表(Wares_info)中的haspic字段,添加商品额外属性表(Wares_ex_property)和商品额外信息表(Wares_ex_info)2个表来完成添加新属性的功能。

    商品额外属性表(Wares_ex_property)

    名称 类型 约束条件 说明
    ex_pid int 无重复 商品额外属性标识,主键
    p_name char(20) 不允许为空 额外属性名称

    商品额外信息表(Wares_ex_info)

    名称 类型 约束条件 说明
    ex_iid int 无重复 商品额外信息标识,主键
    wares_id int 不允许为空 所属商品标识,和Wares_info.wares_id关联
    property_id int 不允许为空 商品额外属性标识,和Wares_ex_property.ex_pid关联
    property_value char(200) 不允许为空 商品额外属性值

    在商品额外属性表(Wares_ex_property)中添加2条记录:
    ex_pid p_name
    1 商品图片
    2 商品长度

    再在整个电子商务平台的后台管理功能中追加一项商品额外属性管理的功能,以后添加新的商品时出现新的属性,只需利用该功能往商品额外属性表(Wares_ex_property)中添加一条记录即可。不要害怕变化,被第一颗子弹击中并不是坏事,坏的是被相同轨道飞来的第二颗、第三颗子弹击中。第一颗子弹来得越早,所受的伤越重,之后的抵抗力也越强8)

    三、多用户及其权限管理的设计

    开发数据库管理类的软件,不可能不考虑多用户和用户权限设置的问题。 尽管目前市面上的大、中型的后台数据库系统软件都提供了多用户,以及细至某个数据库内某张表的权限设置的功能,我个人建议:一套成熟的数据库管理软件,还是应该自行设计用户管理这块功能,原因有二:

    1.那些大、中型后台数据库系统软件所提供的多用户及其权限设置都是针对数据库的共有属性,并不一定能完全满足某些特例的需求;

    2.不要过多的依赖后台数据库系统软件的某些特殊功能,多种大、中型后台数据库系统软件之间并不完全兼容。否则一旦日后需要转换数据库平台或后台数据库系统软件版本升级,之前的架构设计很可能无法重用。

    下面看看如何自行设计一套比较灵活的多用户管理模块,即该数据库管理软件的系统管理员可以自行添加新用户,修改已有用户的权限,删除已有用户。首先,分析用户需求,列出该数据库管理软件所有需要实现的功能;然后,根据一定的联系对这些功能进行分类,即把某类用户需使用的功能归为一类;最后开始建表:

    功能表(Function_table)

    名称 类型 约束条件 说明
    f_id int 无重复 功能标识,主键
    f_name char(20) 不允许为空 功能名称,不允许重复
    f_desc char(50) 允许为空 功能描述

    用户组表(User_group)

    名称 类型 约束条件 说明
    group_id int 无重复 用户组标识,主键
    group_name char(20) 不允许为空 用户组名称
    group_power char(100) 不允许为空 用户组权限表,内容为功能表f_id的集合

    用户表(User_table)

    名称 类型 约束条件 说明
    user_id int 无重复 用户标识,主键
    user_name char(20) 无重复 用户名
    user_pwd char(20) 不允许为空 用户密码
    user_type int 不允许为空 所属用户组标识,和User_group.group_id关联

    采用这种用户组的架构设计,当需要添加新用户时,只需指定新用户所属的用户组;当以后系统需要添加新功能或对旧有功能权限进行修改时,只用操作功能表和用户组表的记录,原有用户的功能即可相应随之变化。当然,这种架构设计把数据库管理软件的功能判定移到了前台,使得前台开发相对复杂一些。但是,当用户数较大(10人以上),或日后软件升级的概率较大时,这个代价是值得的。

    四、简洁的批量m:n设计

    碰到m:n的关系,一般都是建立3个表,m一个,n一个,m:n一个。但是,m:n有时会遇到批量处理的情况,例如到图书馆借书,一般都是允许用户同时借阅n本书,如果要求按批查询借阅记录,即列出某个用户某次借阅的所有书籍,该如何设计呢?让我们建好必须的3个表先:

    书籍表(Book_table)

    名称 类型 约束条件 说明
    book_id int 无重复 书籍标识,主键
    book_no char(20) 无重复 书籍编号
    book_name char(100) 不允许为空 书籍名称
    ……      

    借阅用户表(Renter_table)

    名称 类型 约束条件 说明
    renter_id int 无重复 用户标识,主键
    renter_name char(20) 不允许为空 用户姓名
    ……      

    借阅记录表(Rent_log)

    名称 类型 约束条件 说明
    rent_id int 无重复 借阅记录标识,主键
    r_id int 不允许为空 用户标识,和Renter_table.renter_id关联
    b_id int 不允许为空 书籍标识,和Book_table.book_id关联
    rent_date datetime 不允许为空 借阅时间
    ……      

    为了实现按批查询借阅记录,我们可以再建一个表来保存批量借阅的信息,例如:

    批量借阅表(Batch_rent)

    名称 类型 约束条件 说明
    batch_id int 无重复 批量借阅标识,主键
    batch_no int 不允许为空 批量借阅编号,同一批借阅的batch_no相同
    rent_id int 不允许为空 借阅记录标识,和Rent_log.rent_id关联
    batch_date datetime 不允许为空 批量借阅时间

    这样的设计好吗?我们来看看为了列出某个用户某次借阅的所有书籍,需要如何查询?首先检索批量借阅表(Batch_rent),把符合条件的的所有记录的rent_id字段的数据保存起来,再用这些数据作为查询条件带入到借阅记录表(Rent_log)中去查询。那么,有没有什么办法改进呢?下面给出一种简洁的批量设计方案,不需添加新表,只需修改一下借阅记录表(Rent_log)即可。修改后的记录表(Rent_log)如下:

    借阅记录表(Rent_log)

    名称 类型 约束条件 说明
    rent_id int 无重复 借阅记录标识,主键
    r_id int 不允许为空 用户标识,和Renter_table.renter_id关联
    b_id int 不允许为空 书籍标识,和Book_table.book_id关联
    batch_no int 不允许为空 批量借阅编号,同一批借阅的batch_no相同
    rent_date datetime 不允许为空 借阅时间
    ……      

    其中,同一次借阅的batch_no和该批第一条入库的rent_id相同。举例:假设当前最大rent_id是64,接着某用户一次借阅了3本书,则批量插入的3条借阅记录的batch_no都是65。之后另外一个用户租了一套碟,再插入出租记录的rent_id是68。采用这种设计,查询批量借阅的信息时,只需使用一条标准T_SQL的嵌套查询即可。当然,这种设计不符合3NF,但是和上面标准的3NF设计比起来,哪一种更好呢?答案就不用我说了吧。

    五、冗余数据的取舍

    上篇的“树型关系的数据表”中保留了一个冗余字段,这里的例子更进一步——添加了一个冗余表。先看看例子:我原先所在的公司为了解决员工的工作餐,和附近的一家小餐馆联系,每天吃饭记账,费用按人数平摊,月底由公司现金结算,每个人每个月的工作餐费从工资中扣除。当然,每天吃饭的人员和人数都不是固定的,而且,由于每顿工作餐的所点的菜色不同,每顿的花费也不相同。例如,星期一中餐5人花费40元,晚餐2人花费20,星期二中餐6人花费36元,晚餐3人花费18元。为了方便计算每个人每个月的工作餐费,我写了一个简陋的就餐记账管理程序,数据库里有3个表:

    员工表(Clerk_table)

    名称 类型 约束条件 说明
    clerk_id int 无重复 员工标识,主键
    clerk_name char(10) 不允许为空 员工姓名

    每餐总表(Eatdata1)

    名称 类型 约束条件 说明
    totle_id int 无重复 每餐总表标识,主键
    persons char(100) 不允许为空 就餐员工的员工标识集合
    eat_date datetime 不允许为空 就餐日期
    eat_type char(1) 不允许为空 就餐类型,用来区分中、晚餐
    totle_price money 不允许为空 每餐总花费
    persons_num int 不允许为空 就餐人数

    就餐计费细表(Eatdata2)

    名称 类型 约束条件 说明
    id int 无重复 就餐计费细表标识,主键
    t_id int 不允许为空 每餐总表标识,和Eatdata1.totle_id关联
    c_id int 不允许为空 员工标识标识,和Clerk_table.clerk_id关联
    price money 不允许为空 每人每餐花费

    其中,就餐计费细表(Eatdata2)的记录就是把每餐总表(Eatdata1)的一条记录按就餐员工平摊拆开,是个不折不扣的冗余表。当然,也可以把每餐总表(Eatdata1)的部分字段合并到就餐计费细表(Eatdata2)中,这样每餐总表(Eatdata1)就成了冗余表,不过这样所设计出来的就餐计费细表重复数据更多,相比来说还是上面的方案好些。但是,就是就餐计费细表(Eatdata2)这个冗余表,在做每月每人餐费统计的时候,大大简化了编程的复杂度,只用类似这么一条查询语句即可统计出每人每月的寄餐次数和餐费总帐:

    SELECT clerk_name AS personname,COUNT(c_id) as eattimes,SUM(price) AS ptprice FROM Eatdata2 JOIN Clerk_tabsle ON (c_id=clerk_id) JOIN eatdata1 ON (totleid=tid) WHERE eat_date>=CONVERT(datetime,'"&the_date&"') AND eat_date<DATEADD(month,1,CONVERT(datetime,'"&the_date&"')) GROUP BY c_id

    想象一下,如果不用这个冗余表,每次统计每人每月的餐费总帐时会多麻烦,程序效率也够呛。那么,到底什么时候可以增加一定的冗余数据呢?我认为有2个原则:

    1、用户的整体需求。当用户更多的关注于,对数据库的规范记录按一定的算法进行处理后,再列出的数据。如果该算法可以直接利用后台数据库系统的内嵌函数来完成,此时可以适当的增加冗余字段,甚至冗余表来保存这些经过算法处理后的数据。要知道,对于大批量数据的查询,修改或删除,后台数据库系统的效率远远高于我们自己编写的代码。

    2、简化开发的复杂度。现代软件开发,实现同样的功能,方法有很多。尽管不必要求程序员精通绝大部分的开发工具和平台,但是还是需要了解哪种方法搭配哪种开发工具的程序更简洁,效率更高一些。冗余数据的本质就是用空间换时间,尤其是目前硬件的发展远远高于软件,所以适当的冗余是可以接受的。不过我还是在最后再强调一下:不要过多的依赖平台和开发工具的特性来简化开发,这个度要是没把握好的话,后期维护升级会栽大跟头的。

    展开全文
  • Python-如何设计结构清晰的目录结构

    千次阅读 2018-05-18 14:47:43
    设计项目目录结构”就和”代码编码风格”一样,属于个人风格问题。对于这种风格上的规范,一直都存在两种态度: 一类同学认为,这种个人风格问题”无关紧要”。理由是能让程序work就好,风格问题根本不是问题。 ...

    作者:chen_h
    微信号 & QQ:862251340
    微信公众号:coderpai


    为什么要设计好目录结构

    “设计项目目录结构”就和”代码编码风格”一样,属于个人风格问题。对于这种风格上的规范,一直都存在两种态度:

    1. 一类同学认为,这种个人风格问题”无关紧要”。理由是能让程序work就好,风格问题根本不是问题。

    2. 另一类同学认为,规范化能更好的控制程序结构,让程序具有更高的可读性。

    我是比较偏向于后者的,因为我是前一类同学思想行为下的直接受害者。我曾经维护过一个非常不好读的项目,其实现的逻辑并不复杂,但是却耗费了我非常长的时间去理解它想表达的意思。从此我个人对于提高项目可读性、可维护性的要求就很高了。”项目目录结构”其实也是属于”可读性和可维护性”的范畴,我们设计一个层次清晰的目录结构,就是为了达到以下两点:

    1. 可读性高:不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。

    2. 可维护性高:定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。

    所以,我认为,保持一个层次清晰的目录结构是有必要的。更何况组织一个良好的工程目录,其实是一件很简单的事儿。

    目录组织方式

    关于如何组织一个较好的 Python 工程目录结构,已经有一些得到了共识的目录结构。在Stackoverflow的这个问题上,能看到大家对 Python 目录结构的讨论。

    这里面说的已经很好了,我也不打算重新造轮子列举各种不同的方式,这里面我说一下我的理解和体会。

    假设你的项目名为 foo , 我比较建议的最方便快捷目录结构这样就足够了:

    Foo/
    |-- bin/
    |   |-- foo
    |
    |-- foo/
    |   |-- tests/
    |   |   |-- __init__.py
    |   |   |-- test_main.py
    |   |
    |   |-- __init__.py
    |   |-- main.py
    |
    |-- docs/
    |   |-- conf.py
    |   |-- abc.rst
    |
    |-- setup.py
    |-- requirements.txt
    |-- README

    简要解释一下:

    1. bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。
    2. foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py。
    3. docs/: 存放一些文档。
    4. setup.py: 安装、部署、打包的脚本。
    5. requirements.txt: 存放软件依赖的外部Python包列表。
    6. README: 项目说明文件。

    除此之外,有一些方案给出了更加多的内容。比如 LICENSE.txtChangeLog.txt 文件等,我没有列在这里,因为这些东西主要是项目开源的时候需要用到。如果你想写一个开源软件,目录该如何组织,可以参考这篇文章

    下面,再简单讲一下我对这些目录的理解和个人要求吧。

    关于README的内容

    这个我觉得是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。

    它需要说明以下几个事项:

    1. 软件定位,软件的基本功能。
    2. 运行代码的方法: 安装环境、启动命令等。
    3. 简要的使用说明。
    4. 代码目录结构说明,更详细点可以说明软件的基本原理。
    5. 常见问题说明。

    我觉得有以上几点是比较好的一个 README。在软件开发初期,由于开发过程中以上内容可能不明确或者发生变化,并不是一定要在一开始就将所有信息都补全。但是在项目完结的时候,是需要撰写这样的一个文档的。

    可以参考Redis源码中Readme的写法,这里面简洁但是清晰的描述了Redis功能和源码结构。

    关于requirements.txt和setup.py

    setup.py

    一般来说,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。

    这个我是踩过坑的。

    我刚开始接触Python写项目的时候,安装环境、部署代码、运行程序这个过程全是手动完成,遇到过以下问题:

    1. 安装环境时经常忘了最近又添加了一个新的Python包,结果一到线上运行,程序就出错了。
    2. Python包的版本依赖问题,有时候我们程序中使用的是一个版本的Python包,但是官方的已经是最新的包了,通过手动安装就可能装错了。
    3. 如果依赖的包很多的话,一个一个安装这些依赖是很费时的事情。
    4. 新同学开始写项目的时候,将程序跑起来非常麻烦,因为可能经常忘了要怎么安装各种依赖。

    setup.py 可以将这些事情自动化起来,提高效率、减少出错的概率。”复杂的东西自动化,能自动化的东西一定要自动化。”是一个非常好的习惯。

    setuptools的文档比较庞大,刚接触的话,可能不太好找到切入点。学习技术的方式就是看他人是怎么用的,可以参考一下Python的一个Web框架,flask是如何写的: setup.py

    当然,简单点自己写个安装脚本(deploy.sh)替代setup.py也未尝不可。

    requirements.txt

    这个文件存在的目的是:

    1. 方便开发者维护软件的包依赖。将开发过程中新增的包添加进这个列表中,避免在setup.py安装依赖时漏掉软件包。
    2. 方便读者明确项目使用了哪些Python包。

    这个文件的格式是每一行包含一个包依赖的说明,通常是 flask>=0.10 这种格式,要求是这个格式能被pip识别,这样就可以简单的通过 pip install -r requirements.txt 来把所有Python包依赖都装好了。具体格式说明: 点这里

    关于配置文件的使用方法

    注意,在上面的目录结构中,没有将conf.py放在源码目录下,而是放在docs/目录下。

    很多项目对配置文件的使用做法是:

    1. 配置文件写在一个或多个python文件中,比如此处的conf.py。
    2. 项目中哪个模块用到这个配置文件就直接通过import conf这种形式来在代码中使用配置。

    这种做法我不太赞同:

    1. 这让单元测试变得困难(因为模块内部依赖了外部配置)
    2. 另一方面配置文件作为用户控制程序的接口,应当可以由用户自由指定该文件的路径。
    3. 程序组件可复用性太差,因为这种贯穿所有模块的代码硬编码方式,使得大部分模块都依赖conf.py这个文件。

    所以,我认为配置的使用,更好的方式是,

    1. 模块的配置都是可以灵活配置的,不受外部配置文件的影响。
    2. 程序的配置也是可以灵活控制的。

    能够佐证这个思想的是,用过nginx和mysql的同学都知道,nginx、mysql这些程序都可以自由的指定用户配置。

    所以,不应当在代码中直接import conf来使用配置文件。上面目录结构中的conf.py,是给出的一个配置样例,不是在写死在程序中直接引用的配置文件。可以通过给main.py启动参数指定配置路径的方式来让程序读取配置内容。当然,这里的conf.py你可以换个类似的名字,比如settings.py。或者你也可以使用其他格式的内容来编写配置文件,比如settings.yaml之类的。

    对于文档的态度

    目录结构中有设docs/这个目录,用于存放代码文档。实际过程中,据我观察,80%以上的程序员都没有单独写文档的习惯。一般文档写得比较好的,都是一些开源项目。

    在普通的项目中,确实没必要写非常详细的文档,我更赞同的是现在的一种流行的风格: “在代码中写文档”。即在写代码的时候,在代码文件里把软件/模块的简要用法写明。简单有用。

    小结

    Foo/
    |-- bin/
    |   |-- foo
    |
    |-- foo/
    |   |-- tests/
    |   |   |-- __init__.py
    |   |   |-- test_main.py
    |   |
    |   |-- __init__.py
    |   |-- main.py
    |
    |-- docs/
    |   |-- conf.py
    |   |-- abc.rst
    |
    |-- setup.py
    |-- requirements.txt
    |-- README

    另外,多翻翻经典项目的源码是有好处的,比如在python web开发中比较有名的框架: flask, tornado, django 都是类似的结构。


    来源:monklof

    展开全文
  • 结构化分析和设计常见

    万次阅读 2019-04-26 23:21:07
    描述程序逻辑时,表示嵌套和层次关系,并具有强烈的结构化特征
  • 常见的大型软件项目开发文件目录结构1. Java 项目调试阶段编译后的 .class 文件放到 classes 目录。将 classes 目录和 lib 中的其他工具 .jar 放到 classpath 中。运行当前目录是项目根目录。正式发行版的 .class 放...
  • "设计项目目录结构",就和"代码编码风格"一样,属于个人风格问题。对于这种风格上的规范,一直都存在两种态度: 1.一类同学认为,这种个人风格问题"无关紧要"。理由是能让程序work就好,风格问题根本不是问题。 2....
  • *理解JavaWeb目录结构

    千次阅读 2021-04-30 21:15:17
    额外了解到的java项目常见目录结构3.搜索controller的时候出现三层架构总结 前言 最近在做毕设题目自己拟好后,在网上找了很多开源项目,但是发现一些很规整的javaweb的目录结构不是太懂 我想弄清楚: 写目录结构的...
  • 数据结构常见问题

    千次阅读 2019-06-30 22:07:15
    1.下列关于存储结构和逻辑结构...B选项:算法的设计和数据的逻辑结构有关(选择到底是用图还是用线性表来作为实际问题的某型),算法的实现效率和数据的物理结构有关(选择到底是用那种物理结构实现图或线性表)。 ...
  • Ubuntu文件目录结构详解

    万次阅读 多人点赞 2017-11-23 17:06:00
    1、对于每一个Linux Ubuntu系统学习者来说,了解Linux文件系统的目录结构是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面我们就开始了解...
  • 常见的数据结构及其特征

    千次阅读 2017-03-23 15:39:21
    常见的数据结构有stack、heap、list、linkedlist、doubly-linked-list、queue、array(vector)等
  • 10个常见软件体系结构模式

    万次阅读 2018-05-07 14:06:04
     因此,在将它们应用于我们的设计之前,我们应该了解不同的体系结构。什么是建筑模式?根据维基百科,架构模式是在特定环境下软件体系结构常见问题的通用可重用解决方案。架构模式类似于软件设计模式,但具有更广...
  • 常见结构化存储系统架构

    千次阅读 2019-03-01 22:39:24
    结构化数据一般指存储在数据库中,具有一定逻辑结构和物理结构的数据,最为常见的是存储在关系数据库中的数据;非结构化数据:一般指结构化数据以外的数据,这些数据不存储在数据库中,而是以各种类型的文本形式存放...
  • 一、概述 软件体系结构表示系统的框架结构,用于从较高的层次上来描述各部分之间的关系和接口,主要包括...软件框架设计的核心问题是能否复用已经成型的体系结构方案。由此,产生了软件体系结构风格的概念。 ...
  • 数据结构课程设计

    万次阅读 多人点赞 2018-07-10 15:09:08
    目录 1. 需求分析: 4 1.1问题描述: 4 ...3.1存储结构设计 6 3.1.1顺序查找的基本思想 6 3.1.2二分法查找(折半查找)的基本思想 7 3.1.3斐波那契查找的前提是待查找的查找表必须顺序存...
  • 图解!24张图彻底弄懂九大常见数据结构

    万次阅读 多人点赞 2020-05-24 22:23:36
    线性结构包括常见的链表、栈、队列等,非线性结构包括树、图等。数据结构种类繁多,本文将通过图解的方式对常用的数据结构进行理论上的介绍和讲解,以方便大家掌握常用数据结构的基本知识。 本文提纲: 1数组 ...
  • public interface IDiscount { double salePrice(double originalPrice); }
  • 网站的栏目和目录结构规划方法

    千次阅读 2013-08-09 09:45:55
    网站建设公司在制作网站前如何协助客户整理...如果网站结构不清晰,内容庞杂。这样必然会导致浏览者看得糊涂,也会使网站扩充和维护变得相当困难。定好网站的题材,并收集好相关的资料以后,如何组织内容才能吸引网民来
  • 数据库表结构设计

    万次阅读 2018-02-13 14:33:02
    为什么要学习数据表结构设计 实际开发中,需要根据需求,将实际模型转换成物理表结构,这时需要考虑几个问题,表名称如何命名,表中需要哪些字段,各个字段的命名规范,字段的数据类型,字段的长度,和其他表的联系...
  • Linux目录结构和作用

    万次阅读 多人点赞 2018-03-20 14:02:59
    常见目录说明】目录 /bin存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里。/etc存放系统管理和配置文件/home存放所有用户文件的根目录,是用户主目录的基点,比如用户user的主目录就是/home/user,...
  • MySQL数据库表结构设计优化技巧总结

    千次阅读 2015-02-09 15:51:05
    很多人都将 数据库设计范式 作为数据库表结构设计“圣经...这里我整理了一些比较常见的数据库表结构设计方面的优化技巧,希望对大家有用。  由于MySQL数据库是基于行(Row)存储的数据库,而数据库操作 IO 的时候是以
  • 数据结构与算法常见笔试题

    万次阅读 多人点赞 2017-09-10 11:03:57
    1.数据结构与算法常见笔试题   第一章 数据结构与算法 一.算法的基本概念 计算机解题的过程实际上是在实施某种算法,这种算法称为计算机算法。 1.算法的基本特征:可行性,确定性,有穷性,拥有足够的情报。 2....
  • 浅谈MySQL表结构设计

    万次阅读 2017-12-27 09:48:18
     有一小阵子没有更新技术文章了,今天我们继续MySQL系列,今天要说的是MySQL表结构设计。在我的工作经历当中,就踩过很多这方面的坑,在之前的文章《MySQL表设计踩过的坑!》中,也谈到了一些坑,但总有一种,只是...
  • 2018数据结构课程设计报告

    万次阅读 多人点赞 2018-03-24 16:32:59
    本文是一份数据结构课程设计报告,旨在为各位的课设设计提供一条思路。
  • 面试中常见的数据结构与算法

    万次阅读 多人点赞 2018-04-09 15:53:58
    精确程度由用户的具体设计决定;做到100%的精确即正确是不可能的。 布隆过滤器的优势在于,利用很少的空间可以做到精确率较高。 布隆过滤器的bitarray大小如何确定? 大小为m(过小),样本数量为 n (相较于...
  • Linux源代码目录结构说明

    千次阅读 2016-07-25 10:13:34
    Linux源代码目录结构说明  系统核心组件:  Linux源代码目录结构示意图:  图:linux源代码目录结构示意图(一) scripts目录: 该目录中不包含任何核心代码,该目录下存放了用来配置内核的脚本和应用程序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 508,647
精华内容 203,458
关键字:

常见网站目录结构设计