tomato

tomato 查看完整档案

杭州编辑  |  填写毕业院校  |  填写所在公司/组织 github.com/luyunhua 编辑
编辑

1个在coding路上越走越迷茫的coder

个人动态

tomato 赞了文章 · 2018-11-16

电商系统设计之购物车

9Hb9-fxzvcvh0148760.jpg

本章适合初级工程师及中级工程师细看,大佬请随意

前言

  • 问 [不存价格字段不行吗?直接查询商品表获取价格]
  • 答 [如果价格更新,应提示用户,商品的浮动信息。可以选择直接更新购物车,或者单独建立一个表,来记录更新的价格和信息,类似京东]
  • 问 [联表查询可以从商品表中知道商品是否上架]
  • 答 [商品不存在了如何联,只会将逻辑整复杂,未来包括降价提醒,无货提醒,下架提醒,购物车该如何查询就成了一个问题]



上一篇文章在对于购物车业务及数据表设计中,有位童鞋在评论区与我讨论许久,特此独立一篇文章来详解下我的想法及我为什么这么做,以下为在业务层面、逻辑层面、未来功能的可扩展性、编码的复杂度、数据统计层面来解释下我的设计。

业务

clipboard.png

业务上来看,无论是多表查还是单表存都是合理的,列出以下在购物车上的相关部分业务

  • 库存不足提醒 (提高付款概率)
  • 降价提醒 (提高付款概率)
  • 商品下架提醒
  • 有关商品的商品优惠券或其他活动 (提高付款概率)

以技术角度说明

降价提醒

多表的降价提醒需要第三张表支撑 <商品修改记录表>

多表

clipboard.png

这时购物车内的商品与商品表存在关联,检测降价的系统就需要在商家修改价格时将检测结果后查询加入本商品的购物车,顺便去查询商家修改前价格,算出差价,发送到队列或者其他的手段,用户接收到降价通知,刺激消费。这时你发现,这貌似没有什么地方有问题,如果这时候需要增加一个业务,按照用户加入购物车的时间,提示他在加入购物车后这段时间降价多少?这时是否需要在来个加入购物车的记录表,这样不断的多级关联,看似没有问题,实际将业务耦合,一次sql要关联N个表,如果这时增加sku和spu那就更不用说了。在未来量级上升后是支撑不住的,并且也不方便扩展。

单表

clipboard.png

[我的设计并不是最好的,仅此参考] , 在考虑到未来业务不断增加的问题,我是将价格与标题和商品的SKU加入到购物车表内,在商户修改时无需关心其他表,直接检索与修改商品相关的购物车,拿出价格,计算差价,提示用户。如果计算加入购物车这段实际降价多少,这其实与上述操作一样,对于单表的设计上,这2种需求实为一种解决方案。在查询上也是一条sql语句的实现。

当然,我们还是需要关联上,不知道未来的某一天就用的上了呢?
有很多场景,都要将标题呀,内容呀直接存储,类似与收藏的店铺和商品,无论卖家怎么做,用户购物车,订单不能动,这是基准。

商品下架

商品下架,用户的购物车实际是不能动的,某猫的做法是使其变灰,让用户自行删除。
商家分很多种,商品的标题,图片或者分类修改了,都属于下架,这时的多表关联查询就彻彻底底的失效了。
其实商品的下架应该直接通知购物车下架 (变灰),并非关联查询是否下架。如果你非要这样做,那你依旧需要做一些表去记录。

我并不是说不需要做记录。而是记录的表实际是不参与业务查询的。

逻辑

逻辑这里特指代码的架构编写。以php为例,可以参考我之前的文章 https://segmentfault.com/a/11...
在逻辑方面,要考虑方面比较多,类似sql的性能,代码的性能,服务器的性能等。尽量避免多表查询吧。

可复用性

百度百科的定义是

可复用性(Reuseability)复用又叫重用,是重复使用的意思。目前,一般软件的复用率并不高,尤其在国内。复用的好处可以得到 较高的生产效率以及随之而来的成本降低、较高的软件质量(错误可以更快的被纠正)以及 恰当的使用复用可以改善系统的可维护性。

在购物车的设计上,重用主要提现在商品信息的存储方式上,避免多次去联表查询,在业务量大后的份表分库提现会更明显。

可扩展性

百度百科的定义是:

设计良好的代码允许更多的功能在必要时可以被插入到适当的位置中。这样做的目的的是为了应对未来可能需要进行的修改,而造成代码被过度工程化地开发。

正常购物车、商品、优惠券都是独立的系统及功能,不要看做商品在购物车内。现实和逻辑并非是一脉相承的。就假设在实际生活中,物品仅仅是放在购物车中,如果不结账,依旧不属于自己。为了方便扩展更多业务,尽量在设计之初,功能与功能之间不要“粘”在一起。

可维护性

百度百科的定义是:

系统的可维护性是衡量一个系统的可修复(恢复)性和可改进性的难易程度。所谓可修复性是指在系统发生故障后能够排除(或抑制)故障予以修复,并返回到原来正常运行状态的可能性。而可改进性则是系统具有接受对现有功能的改进,增加新功能的可能性。

购物车的设计之初也是考虑未来商品的业务功能各种变更。不如简单点,直接将其属性存到购物车。

复杂度

初期的设计,决定未来开发及重构的复杂度。功能与功能,系统与系统之间尽量避免直接关联。

统计

后期的数据统计、计算也会受到前期设计的影响。

致谢

感谢你们看到这里,下一篇我会讲一下关于电商系统的商品设计的部分。有什么问题可以评论区提问。谢谢

查看原文

赞 40 收藏 44 评论 1

tomato 回答了问题 · 2018-08-28

表单页面 input 条数确定 如何设计数据库表

mysql5.7 后支持json存储类型 你这种情况比较适合json
如果使用分隔符形式 无法进行搜索 只能通过取出所有数据后 程序进行查找运算

关注 4 回答 3

tomato 回答了问题 · 2018-08-28

php7 开启opcache时接口没有返回最新数据

请重启php-fpm尝试一下

关注 3 回答 2

tomato 回答了问题 · 2018-08-28

php中图片禁止http访问。

a.gif可以被网络访问
然后a可以访问 b不可以访问 http是无状态协议 你这张图片压根不知道是谁在访问自己
除非你站内的图片都通过nginx location 重新定位到一段程序 然后根据是否是本站用户决定是否显示图片
but这样的操作实在奇怪
可以这样

location /showimg/ {
     #[config] 程序配置
}

location ~* \.(gif|jpg|jpeg)$ {
        rewrite (.*) /showimg/$1 last;
}

关注 3 回答 2

tomato 发布了文章 · 2018-04-16

自己用的gitconfig 记录一下

[push]
    default = current
[user]
    email = luyunhua@xxx.cn
    name = luyunhua
[alias]
    co = checkout
    ci = commit
    br = branch
    st = status
    lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
[credential]
    helper = store
查看原文

赞 0 收藏 0 评论 0

tomato 发布了文章 · 2018-01-15

Go语言入门教程 - Hello World

Go语言入门教程 - Hello World

这是Go语言入门教程的第二篇教程。在进入第二篇教程之前,请阅读第一部分简介和安装知晓如何安装golang。

没有更好的方法能比我们手把手的敲代码来学习程序语言来的快了。那么让我们赶紧去写我们的第一个程序吧。

我个人推荐使用 Visual Studio Code 作为go语言的编辑器,它支持自动补全,代码样式(如:高亮)和其他很多功能。

设置workspace

在开始编码之前,我们必须设置go语言的workspace。

在Mac、Linux 环境下,我们将workspace设置为 $HOME/go。我们可以使用 mkdir ~/go 命令创建该目录。

在Windows环境下,我们将workspace应被设置为C:\Users\YourName\go,我们可以使用 mkdir C:\Users\YourName\go 命令创建该目录。

通过设置GOPATH环境变量,我们可以使用不同的目录作为workspace,但是现在我们就简单的按照上面的设置即可。

所有的源代码文件应该被放在一个叫src的目录中,接下来我们在go 目录中创建src 目录。

每一个 go 项目 都应该在src 目录中有一个对应的子目录。让我们首先来创建一个hello的新目录用来存放hello world项目的代码。

在我们创建完目录后,目录结构看起来如下所示

    go
      src
         hello

保存以下代码并命名为helloworld.go 在我们刚创建的hello文件夹中。

package main

import "fmt"

func main() {  
    fmt.Println("Hello World")
}

创建完上面的程序文件后,我们的目录结构看起来是这样子的

go
  src
     hello
          helloworld.go

运行 go 程序

下面是一组运行一个go程序的俩种方法。让我们一个个来看

1) 在命令提示符中输入 go run workspacepath/src/hello/helloworld.go

上面代码要能正常运行的前提是,工作空间(workspace)已经设置完毕。
windows: C:/Users/YourName/go, linux or Mac: $HOME/go

接下来你会看到在终端会输出Hello World

2) 使用 go install hello 编译并安装hello工程,然后使用 workspacepath/bin/hello 运行程序

上面代码要能正常运行的前提是,工作空间(workspace)已经设置完毕。
windows: C:/Users/YourName/go, linux or Mac: $HOME/go

当我们使用go install hello 命令后,go tool会搜索hello 这个包(hello 被称作包,我们会在包那一节详细介绍) 在workspace。然后会在bin目录生成一个叫hello(在windows中是hello.exe)的二进制文件。然后我们的目录结构是这样的。

go
         bin  
           hello
         src
           hello
               helloworld.go

hello world 程序的简单解释

下面是我们刚才写的程序代码

package main //1

import "fmt" //2

func main() { //3  
    fmt.Println("Hello World") //4
}

package main - 每一个go程序必须以 package name 开头. 包的设计主要用来做代码隔离和代码可复用. 这段程序里面的包名叫做 main

import "fmt" - 导入fmt包用来在main函数中的输出文字到标准输出设备

func main() - main函数是一个特殊的函数. 应用程序从main函数开始执行. main 函数必须被放在main包中. The { and } indicate the start and end of the main function.

fmt.Println("Hello World") - 使用fmt包中的Println用来输出文字到标准输出设备

查看原文

赞 1 收藏 0 评论 0

tomato 发布了文章 · 2018-01-11

Go语言入门教程-介绍和安装

备注: 由于年前工作事情较多,我会在过年前完成翻译整理工作

这是go语言入门的第一篇教程

什么是Golang

Go是谷歌创建的,开放源代码、编译型和静态类型的编程语言.

Golang 的主要关注点在使开发高可用和可伸缩的web应用程序更加简单和容易.

为什么选择Golang

为什么在有这么多其他编程语言的前提下要选择Golang作为服务端编程语言?

以下是我找到的一些关于Go语言的优点

  • 可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
  • 静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
  • 语言层面支持并发,这个就是Go最大的特色,天生的支持并发,我曾经说过一句话,天生的基因和整容是有区别的,大家一样美丽,但是你喜欢整容的还是天生基因的美丽呢?Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
  • 内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。

简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。

  • 丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大,我最爱的也是这部分。
  • 内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
  • 跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
  • 内嵌C支持,前面说了作者是C的作者,所以Go里面也可以直接包含c代码,利用现有的丰富的C库。

Go适合用来做什么

  • 服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
  • 分布式系统,数据库代理器等
  • 网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用、
  • 内存数据库,前一段时间google开发的groupcache,couchbase的部分组建
  • 云平台,目前国外很多云平台在采用Go开发,CloudFoundy的部分组建,前VMare的技术总监自己出来搞的apcera云平台。

安装

Golang 支持所有第三方操作系统 Mac, Windows, Linux. 你可以从以下链接下载相应平台的二进制文件 https://golang.org/dl/

Mac OS

https://golang.org/dl/下载OS X 安装器
双击开始安装.根据安装提示安装完成后,Golang被安装在 /usr/local/go 目录中,/usr/local/go/bin 会被加入到系统环境变量中.

Windows

https://golang.org/dl/下载Msi 安装器.双击安装文件根据安装提示直到安装完成.Golang会被安装在 c:\Go 目录, c:\Go\bin目录会被加入到系统环境变量中

Linux

https://golang.org/dl/下载tar文件, 使用unzip命令解压至/usr/local目录, 添加/usr/local/go/bin 到系统环境变量中.

查看原文

赞 2 收藏 3 评论 1

tomato 回答了问题 · 2017-12-01

解决Mac修改apache默认目录后重启,safari表示无法连接服务器

会不会是apache 没有读取你新创建的目录权限 查看下apache 的错误日志

关注 3 回答 3

tomato 赞了回答 · 2017-12-01

PHP有什么办法可以排查那些脚本或方法执行慢,需要优化?

楼上几位的回答的都差不多了 , 我也废话几句昂 :

  1. 最俗气的解决方案就是打tick time,执行前来个microtime,执行完毕后来个microtime,然后一减,你就知道了。
  2. 比较彻底的解决方案还是有明提的xhprof扩展,该扩展可以生成代码耗费的cpu memory以及时间。但是该扩展只支持php5,支持php7的xhprof是github上另外一个哥们维护的,不是facebook官方,两个都没问题,都可以用
  3. 商用解决方案,接入某些APM厂商,也是可以解决问题的,避免广告嫌疑,这个我就不举例了

关注 11 回答 8

tomato 回答了问题 · 2017-11-28

这种类型的json怎么解析

<?php

$str = <<<EOF
reqparam={
    "pub": {
        "platno": "jcrzzl",
        "cmpseq": "20171128000358000001",
        "zoneno": "1302",
        "phybrno": "12032150",
        "orderno": "-9223372036854775808",
        "assurerno": "528",
        "cmpdate": "20171128",
        "cmptime": "000358"
    },
    "req": {
        "custname": "小明",
        "idno": "330681199003000004",
        "relation": "本人",
        "result": "099",
        "loanCrdt": "-",
        "cardCrdt": "-",
        "leftNum": "-",
        "leftAmount": "-",
        "note": "图片下载失败,请检查后再提交!"
    }
}
EOF;

$replaced_str = str_replace('reqparam=', '', $str);
$json = json_decode($replaced_str, true);
print_r($json);

clipboard.png

关注 12 回答 11

认证与成就

  • 获得 43 次点赞
  • 获得 6 枚徽章 获得 0 枚金徽章, 获得 1 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2015-04-22
个人主页被 1.6k 人浏览