Home  >  Article  >  Database  >  MySQL和MongoDB设计实例对比_MySQL

MySQL和MongoDB设计实例对比_MySQL

WBOY
WBOYOriginal
2016-06-01 13:11:22858browse

MongoDB

本文转载自火丁笔记,文章举了一个数据库设计的例子,对MySQL和MongoDB两种存储工具,分别进行了数据库结构设计,在MongoDB的设计上,利用了MongoDB的 schema-free的特性。

虽然文中的例子不一定是最优的选择。但分享此文,希望提醒大家,换个存储,不仅是换一个存储,更重要的是换一套思维。

MySQL是关系型数据库中的明星,MongoDB是文档型数据库中的翘楚。下面通过一个设计实例对比一下二者:假设我们正在维护一个手机产品库,里面除了包含手机的名称,品牌等基本信息,还包含了待机时间,外观设计等参数信息,应该如何存取数据呢?

如果使用MySQL的话,应该如何存取数据呢?

如果使用MySQL话,手机的基本信息单独是一个表,另外由于不同手机的参数信息差异很大,所以还需要一个参数表来单独保存。

CREATE TABLE IF NOT EXISTS `mobiles` (    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,    `name` VARCHAR(100) NOT NULL,    `brand` VARCHAR(100) NOT NULL,    PRIMARY KEY (`id`));  CREATE TABLE IF NOT EXISTS `mobile_params` (    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,    `mobile_id` int(10) unsigned NOT NULL,    `name` varchar(100) NOT NULL,    `value` varchar(100) NOT NULL,    PRIMARY KEY (`id`));  INSERT INTO `mobiles` (`id`, `name`, `brand`) VALUES(1, 'ME525', '摩托罗拉'),(2, 'E7'   , '诺基亚');  INSERT INTO `mobile_params` (`id`, `mobile_id`, `name`, `value`) VALUES(1, 1, '待机时间', '200'),(2, 1, '外观设计', '直板'),(3, 2, '待机时间', '500'),(4, 2, '外观设计', '滑盖');

注:为了演示方便,没有严格遵守关系型数据库的范式设计。

如果想查询待机时间大于100小时,并且外观设计是直板的手机,需按照如下方式查询:

SELECT * FROM `mobile_params` WHERE name = '待机时间' AND value > 100;SELECT * FROM `mobile_params` WHERE name = '外观设计' AND value = '直板';

注:参数表为了方便,把数值和字符串统一保存成字符串,实际使用时,MySQL允许在字符串类型的字段上进行数值类型的查询,只是需要进行类型转换,多少会影响一点性能。

两条SQL的结果取交集得到想要的MOBILE_IDS,再到mobiles表查询即可:

SELECT * FROM `mobiles` WHERE mobile_id IN (MOBILE_IDS)

如果使用MongoDB的话,应该如何存取数据呢?

如果使用MongoDB的话,虽然理论上可以采用和MySQL一样的设计方案,但那样的话就显得无趣了,没有发挥出MongoDB作为文档型数据库的优点,实际上使用MongoDB的话,和MySQL相比,形象一点来说,可以合二为一:

db.getCollection("mobiles").ensureIndex({    "params.name": 1,    "params.value": 1});  db.getCollection("mobiles").insert({    "_id": 1,    "name": "ME525",    "brand": "摩托罗拉",    "params": [        {"name": "待机时间", "value": 200},        {"name": "外观设计", "value": "直板"}    ]});  db.getCollection("mobiles").insert({    "_id": 2,    "name": "E7",    "brand": "诺基亚",    "params": [        {"name": "待机时间", "value": 500},        {"name": "外观设计", "value": "滑盖"}    ]});

如果想查询待机时间大于100小时,并且外观设计是直板的手机,需按照如下方式查询:

db.getCollection("mobiles").find({    "params": {        $all: [            {$elemMatch: {"name": "待机时间", "value": {$gt: 100}}},            {$elemMatch: {"name": "外观设计", "value": "直板"}}        ]    }});

注:查询中用到的$all,$elemMatch等高级用法的详细介绍请参考官方文档中相关说明。

MySQL需要多个表,多次查询才能搞定的问题,MongoDB只需要一个表,一次查询就能搞定,对比完成,相对MySQL而言,MongoDB显得更胜一筹,至少本例如此。


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn