数据可以存储在内存中、文件中、按二进制序列化存储的文件中、数据库中等。

内存存储

将数据存储到内存中。此处所指的内存是指应用程序自身的内存空间(如slice、array、map、struct、队列、树等等容器),而不是外部的内存数据库(如redis)。

例如,要存储博客文章。

每篇博客文章都有文章ID、文章内容以及文章作者(关于博客类文章,一般还有浏览量、点赞数量、评论、文章发表时间、文章是否置顶、标签、是否转载等等属性)。假设它是一个struct结构:

type Post struct {
Id int
Content string
Author string
}

为了在内存中存储每一篇Post,可以考虑将每篇Post放进一个slice,也可以放进map。因为id或author或content和文章之间有映射关系,使用map显然更好一些。

var PostById map[int]*Post

这样就能通过Id来检索对应的文章,注意上面map的value是指针类型的,不建议使用值类型的,这样会产生副本。

如果想要通过Author来检索文章,则还可以使用一个map来存储这个作者下的所有文章。因为一个作者可以有多篇文章,所以map的value应该是一个容器,比如slice。

var PostsByAuthor map[string][]*Post

还可以关键字来检索Content从而找出关键字近似的文章,也就是搜索引擎类型的检索方式。这个比较复杂一些。

还有一些文章设置了标签关键字,比如linux类的文章,docker标签的文章,shell标签的文章等。为了可以使用标签检索文章,还需要创建一个按照标签方式进行存储文章的map容器。关于标签的存储方式,此处略过。

现在假设就前面定义的两种存储方式:PostById和PostsByAuthor,定义提交文章的函数:

func store(post *Post) {
PostById[post.Id] = post
PostsByAuthor[post.Author] = append(PostByAutor[post.Autor], post)
}

注意,上面store()函数的参数是指针类型的。

文章存储到上面两种容器中后,就可以从任意一种容器中检索文章。因为存储时是使用指针类型存储的,所以无论从哪一种容器中检索得到的文章,和另一种方式检索得到的是相同的文章。

例如:

// 按文章Id检索文章并输出文章的Content
fmt.Println(PostById[1])
fmt.Println(PostById[2]) // 按作者检索文章并输出文章的Content
for _, post := range PostsByAuthor["userA"]{
fmt.Println(post)
}

下面是完整的代码:

package main

import (
"fmt"
) type Post struct {
Id int
Content string
Author string
} // 用于存储的两个内存容器
var PostById map[int]*Post
var PostsByAuthor map[string][]*Post // 存储数据
func store(post *Post) {
PostById[post.Id] = post
PostsByAuthor[post.Author] = append(PostsByAuthor[post.Author], post)
} func main() {
PostById = make(map[int]*Post)
PostsByAuthor = make(map[string][]*Post)
post1 := &Post{Id: 1, Content: "Hello 1", Author: "userA"}
post2 := &Post{Id: 2, Content: "Hello 2", Author: "userB"}
post3 := &Post{Id: 3, Content: "Hello 3", Author: "userC"}
post4 := &Post{Id: 4, Content: "Hello 4", Author: "userA"}
store(post1)
store(post2)
store(post3)
store(post4)
fmt.Println(PostById[1])
fmt.Println(PostById[2])
for _, post := range PostsByAuthor["userA"] {
fmt.Println(post)
}
for _, post := range PostsByAuthor["userC"] {
fmt.Println(post)
}
}

执行结果:

&{1 Hello 1 userA}
&{2 Hello 2 userB}
&{1 Hello 1 userA}
&{4 Hello 4 userA}
&{3 Hello 3 userC}

Go Web:数据存储(1)——内存存储的更多相关文章

  1. web数据存储

    数据的存储必然是任何网站必须经历的事,我们可以将数据存放在不同地方,数据库.文件.内存.程序本身.cookie,session中都可以,但是只要需要持久化保留的数据,那么最终肯定还是落在磁盘之上的,我 ...

  2. 多台web如何共享session进行存储(转载)

    session的存储了解以前是怎么做的,搞清楚了来龙去脉,才会明白进行共享背后的思想和出发点.我喜欢按照这样的方式来问(或者去搞清楚):为什么要session要进行共享,不共享会什么问题呢? php中 ...

  3. 文件存储之-内存文件系统tmpfs

    前言 我们都知道,对于单台服务器来说,除了 CPU ,内存就是我们存储数据最快的设备.如果可以把数据直接存储在内存中,对于性能的提升就不言而喻了.那么我们先来讲讲如何使用内存来存储文件. 首先,我们先 ...

  4. Azure Storage 系列(二) .NET Core Web 项目中操作 Blob 存储

    一,引言 上一篇文章,我们介绍到在实际项目中系统会产生大量的日志文件,用户上传的头像等等,同时也介绍到可以使用Azure Blob Storage 来存储项目中的一些日志文件,用户头像,用户视频等等. ...

  5. 亿级用户下的新浪微博平台架构 前端机(提供 API 接口服务),队列机(处理上行业务逻辑,主要是数据写入),存储(mc、mysql、mcq、redis 、HBase等)

    https://mp.weixin.qq.com/s/f319mm6QsetwxntvSXpKxg 亿级用户下的新浪微博平台架构 炼数成金前沿推荐 2014-12-04 序言 新浪微博在2014年3月 ...

  6. Redis内存存储结构分析

    1 Redis 内存存储结构 本文是基于 Redis-v2.2.4 版本进行分析. 1.1 Redis 内存存储总体结构 Redis 是支持多key-value数据库(表)的,并用 RedisDb 来 ...

  7. memcached全面剖析–2. 理解memcached的内存存储

    Slab Allocation机制:整理内存以便重复使用 最近的memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存. 在该机制出现以前,内存的分配是通过对所有记录简 ...

  8. 关于大数据时代传统商业存储的思考: 中心存储 VS 分布式存储

    尊重原创,转载请注明出处:http://anzhan.me ; http://blog.csdn.net/anzhsoft 今天和我们部门的老大1*1, 大家面对面沟通了一下到新的项目组的想法.而且也 ...

  9. 大数据项目之_15_电信客服分析平台_01&02_项目背景+项目架构+项目实现+数据生产+数据采集/消费(存储)

    一.项目背景二.项目架构三.项目实现3.1.数据生产3.1.1.数据结构3.1.2.编写代码3.1.3.打包测试3.2.数据采集/消费(存储)3.2.1.数据采集:采集实时产生的数据到 kafka 集 ...

随机推荐

  1. 初识 Proxysql

    1.ProxySQL 介绍和安装 ProxySQL 是一种高性能.高可用的开源中间件,适用于mysql和相关的数据库,如MariaDB官网:http://www.proxysql.com 安装 发行版 ...

  2. 登陆页、注册页、会员中心页logo图的替换

                  关闭   PHP在线开发笔记       目录视图 摘要视图 订阅 异步赠书:9月重磅新书升级,本本经典           程序员9月书讯      每周荐书:ES6.虚 ...

  3. java解析json数据用到的jar包

    百度云连接: https://pan.baidu.com/s/1iuQCc7uBO5XtAsNn6hwCew

  4. 默认空间和webapps下项目部署

    用eclipse默认的工作区和webapps的细节 用{WORKSPACE}表示你的eclipse的工作空间根目录,然后你打开 {WORKSPACE}\.metadata\.plugins\org.e ...

  5. python基础自学 第三天

    变量的命名 01.标识符和关键字 标识符 标识符就是程序员定义的变量名.函数名. 标识符可以由字母,下划线,和数字组成. 不能以数字开头 不能与关键字重名 关键字 就是在python内部已经使用的标识 ...

  6. Linux(lamp安装)

    网络配置 1. 配置ip地址和子网掩码 编辑配置文件: > cd  /etc/sysconfig/network-scripts > cp  ifcfg-eth0  ./ifcfg-eth ...

  7. day17_雷神_数据库 小全

    # 数据库 1.mysql 介绍 一 数据库管理软件的由来 程序的所有组件不可能只在一个机子上,性能问题和单点故障, 程序分散了,还需要解决数据共享问题, 基于网络访问这台共享的机器,用socket. ...

  8. Python小练习之判断一个日期是一年的第几天

    python练手遇到的一个问题写了个统一公式,不用麻烦的分各种类,如果有人测试出错误请评论通知. #分单双月 def dayNum(month,day,isLeap): if month % 2 != ...

  9. MySQL优化--INSERT ON DUPLICATE UPDATE死锁

    INSERT ON DUPLICATE UPDATE与死锁 在MySQL中提供两种插入更新的方式:REPLACE INTO和INSERT ON DUPLICATE UPDATE,简化了“存在则更新,不 ...

  10. 转载:Package by feature, not layer

    原文地址:Package by feature, not layer Package by feature, not layer The first question in building an a ...