数据库中的分类搜索

        我们在学习数据库的过程中,可以很清楚地了解到,如果要搜索我们需要的数据,就要在WHERE之后添加我们的条件,当然,搜索可以用LIMIT要求获取某个范围的数据,也可以用ORDER  BY来对获取的数据进行排序输出,也可以用MAX(  )或者MIN(  )等函数获取其中的最值,但是如果要分类呢?要怎么写sql语句才能符合我们想获得的数据呢?

        下面举一个简单的例子:

        我这里有一个回复的表格,用来记录所有对某个主题的回复,我先创建这个表格:

CREATE TABLE IF NOT EXISTS reply(
        reply_id INT NOT NULL ,
        subject_id INT NOT NULL ,
        replyer_id INT NOT NULL ,
        reply_content VARCHAR(50) DEFAULT "" ,
        reply_time DATETIME NOT NULL ,
        PRIMARY KEY(reply_id)
      );

        这是一个比较简单的reply(回复)的表格,用来记录其他人对某个主题的回复记录,replt_id是主键,subject_id是回复的主题id,replyer_id是回复人的账号id,而reply_content就是回复的内容,reply_time是回复的时间。

        好了,大概了解了这个表是干什么的了。

        那么现在,如果我想做一件事,展示一下所有的回复内容,那么我应该如何做呢?如果单纯获取所有回复很简单,就一句话:

SELECT * FROM reply;

        但是,我想获取某个主题(假设这个主题id为888)的所有回复内容呢?也是一句话:

SELECT * FROM reply WHERE reply.subject_id=888;

        这也只是在后面加个WHERE条件而已,那如果我需要获取某个主题(假设这个主题id为888)的最后回复时间呢?可以这样写:

SELECT MAX(reply_time), reply_id FROM reply 
WHERE reply.subject_id=888;

        可以用最大值代表最后的回复时间。那又如果我想获取好几个主题(假设这几个主题id为111,333,888)的最后回复时间呢?

        可能瞬间你会想到用IN,这样:

SELECT MAX(reply_time), reply_id FROM reply 
WHERE reply.subject_id IN (111,333,888);

        但是很显然,这是错的,因为你只是在三个主题(111,333,888)下的所有情况搜索出最后的回复时间,而没有每一条主题的回复时间,所以结果最多只有一条。

        当然了,你可以用UNION方法达到效果:

SELECT MAX(reply_time), reply_id FROM reply 
WHERE reply.subject_id=111
UNION
SELECT MAX(reply_time), reply_id FROM reply 
WHERE reply.subject_id=333
UNION
SELECT MAX(reply_time), reply_id FROM reply 
WHERE reply.subject_id=888;

        但是我只给你一个数组呢,要你用IN方法写出来呢?

        那就要从最根本查找语句的逻辑出发了,因为我们是查找某些主题下的最后回复时间,那么我们从整个表中查找的话,那就只需要给我所有的最后回复时间啊,我先不管最后回复时间是怎样来的,我也可以先写出这样的语句:

SELECT reply_time, reply_id FROM reply 
WHERE ……;

        好了,这个时候我们就要考虑怎样获取到所有的主题,这里就要借用一个技巧,借用一下别名,因为我们需要找出所有的主题,那么如何找,那就需要用两个表来确认subject_id相等的地方,那就可以找出所有同一主题的数据,再从中提取最大值,那就可以了:

SELECT reply_time, reply_id FROM reply AS a
WHERE 
(SELECT MAX(b.reply_time) FROM reply AS b 
WHERE
a.subject_id=b.subject
);

        最后,再加上需要查找的subject_id就可以了:

SELECT reply_time, reply_id FROM reply AS a
WHERE 
(SELECT MAX(b.reply_time) FROM reply AS b 
WHERE
a.subject_id=b.subject AND b.subject IN (111,333,888)
);

        上面就是一个简单的分类搜索语句,但是实际应用中,有很多远远复杂的要求,所以对sql语句的掌握也是非常重要的。

文章在我的github上的地址:点击跳转

原创文章,转载请注明出处!

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行许可。

数据库

        什么是数据库,百度解释就是:数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。见名思意,就是存库数据的仓库,由于数据的重要性日益突出,特别数据以几何级数量增长的今天,所以学好数据库技术显得尤其重要。

        数据库通常分为层次式数据库、网络式数据库和关系式数据库三种。而不同的数据库是按不同的数据结构来联系和组织的。而在当今的互联网中,最常见的数据库模型主要是两种,即关系型数据库和非关系型数据库。

        先说说关系型数据库。

        关系型数据库模型是把复杂的数据结构归结为简单的二元关系(即二维表格形式)。在关系型数据库中,对数据的操作几乎全部建立在一个或多个关系表格上,通过对这些关联的表格分类、合并、连接或选取等运算来实现数据库的管理。

        其实可以这样理解,例如有一个数据“我是张三,今年20岁,身高178cm,体重75kg”,那么我们就可以创建一个人员信息的表格,横向有姓名、年龄、身高、体重等字段,纵向就可以保存上述这一条信息。就像我们平时用的excel那样,一个有横竖的表格来存储我们这样的数据,可以通过不同表格的关联来实现增删查改。

        常用的关系型数据库有:Oracle、MySQL、MariaDB、SqlServer、Access等。

        那什么是非关系型数据库呢?

        听说过NoSQL吧,就是Not only SQL的意思,泛指非关系型数据库。这里贴个百度百科的地址:https://baike.baidu.com/item/NoSQL/8828247?fr=aladdin。里面有详细的介绍,这里复制粘贴它的四大分类表格介绍:

分类 Examples举例 典型应用场景 数据模型 优点 缺点
键值(key-value) Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。 Key 指向 Value 的键值对,通常用hash table来实现 查找速度快 数据无结构化,通常只被当作字符串或者二进制数据
列存储数据库 Cassandra, HBase, Riak 分布式的文件系统 以列簇式存储,将同一列数据存在一起 查找速度快,可扩展性强,更容易进行分布式扩展 功能相对局限
文档型数据库 CouchDB, MongoDb Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) Key-Value对应的键值对,Value为结构化数据 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 查询性能不高,而且缺乏统一的查询语法。
图形(Graph)数据库 Neo4J, InfoGrid, Infinite Graph 社交网络,推荐系统等。专注于构建关系图谱 图结构 利用图结构相关算法。比如最短路径寻址,N度关系查找等 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。

        现在NoSQL仿佛是一种风向的趋势,未来有很大的发展空间。当然,关系型数据库还是大型公司的主流,未来的两者发展关系不得而知,不过关系型数据库是不会消亡的。

文章在我的github上的地址:点击跳转

原创文章,转载请注明出处!

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行许可。