>  기사  >  백엔드 개발  >  MongoDB 데이터베이스를 사용하여 제품 정보 저장

MongoDB 데이터베이스를 사용하여 제품 정보 저장

伊谢尔伦
伊谢尔伦원래의
2017-02-06 13:48:011560검색

전자상거래 비즈니스의 기본 기능 모듈은 풍부한 카테고리로 상품 정보를 저장하는 것입니다. 다양한 제품은 서로 다른 특성과 매개변수를 가지고 있습니다. MongoDB의 유연한 문서 모델은 이러한 유형의 비즈니스에 매우 적합합니다. 제품 분류 정보를 저장합니다.

관계형 데이터베이스 솔루션

위의 문제는 다음 솔루션과 같은 기존 관계형 데이터베이스를 사용하여 해결할 수도 있습니다

다른 경우 제품, 서로 다른 테이블 생성

예를 들어 음악 앨범과 영화라는 두 제품에는 몇 가지 공통 속성이 있지만 고유한 속성도 많이 있습니다. 서로 다른 속성을 가진 두 개의 서로 다른 테이블을 생성할 수 있습니다.

CREATE TABLE `product_audio_album` (
    `sku` char(8) NOT NULL,
    ...
    `artist` varchar(255) DEFAULT NULL,
    `genre_0` varchar(255) DEFAULT NULL,
    `genre_1` varchar(255) DEFAULT NULL,
    ...,
    PRIMARY KEY(`sku`))
...
CREATE TABLE `product_film` (
    `sku` char(8) NOT NULL,
    ...
    `title` varchar(255) DEFAULT NULL,
    `rating` char(8) DEFAULT NULL,
    ...,
    PRIMARY KEY(`sku`))
...

이 접근 방식의 주요 문제점은

  1. 각 새로운 제품 카테고리에 대해 새 테이블을 생성해야 한다는 것입니다

  2. 애플리케이션 개발자는 쿼리를 위해 해당 테이블에 요청을 명시적으로 배포해야 합니다. 여러 제품을 동시에 쿼리하는 것은 구현하기가 번거롭습니다

모든 제품이 단일 테이블에 저장됩니다

CREATE TABLE `product` (
    `sku` char(8) NOT NULL,
    ...
    `artist` varchar(255) DEFAULT NULL,
    `genre_0` varchar(255) DEFAULT NULL,
    `genre_1` varchar(255) DEFAULT NULL,
    ...
    `title` varchar(255) DEFAULT NULL,
    `rating` char(8) DEFAULT NULL,
    ...,
    PRIMARY KEY(`sku`))

모든 제품을 테이블에 저장합니다. 각 제품은 필요에 따라 서로 다른 속성을 설정합니다. 이 방법을 사용하면 하나의 쿼리가 여러 제품에 걸쳐 있을 수 있습니다. 공간을 많이 낭비한다는 거죠.

공개 속성 추출, 다중 테이블 상속

CREATE TABLE `product` (
    `sku` char(8) NOT NULL,
    `title` varchar(255) DEFAULT NULL,
    `description` varchar(255) DEFAULT NULL,
    `price`, ...
    PRIMARY KEY(`sku`))
CREATE TABLE `product_audio_album` (
    `sku` char(8) NOT NULL,
    ...
    `artist` varchar(255) DEFAULT NULL,
    `genre_0` varchar(255) DEFAULT NULL,
    `genre_1` varchar(255) DEFAULT NULL,
    ...,
    PRIMARY KEY(`sku`),
    FOREIGN KEY(`sku`) REFERENCES `product`(`sku`))
...
CREATE TABLE `product_film` (
    `sku` char(8) NOT NULL,
    ...
    `title` varchar(255) DEFAULT NULL,
    `rating` char(8) DEFAULT NULL,
    ...,
    PRIMARY KEY(`sku`),
    FOREIGN KEY(`sku`) REFERENCES `product`(`sku`))
...

위 솔루션은 모든 제품의 공통 속성을 추출하고 각 제품에 대해 하나의 테이블에 공개 속성을 저장합니다. 필요에 따라 새 테이블을 만들고, 새 테이블에는 제품에 고유한 정보만 저장합니다.

엔티티 속성 값 양식 저장

모든 데이터는 3-튜플 형태로 실제로 저장됩니다. 이 솔루션은 실제로 관계형 데이터베이스를 KV 저장, 모델 단순으로 사용합니다. , 그러나 복잡한 쿼리에는 그리 편리하지 않습니다.

엔티티                                                                                                         유형 오디오 앨범 sku_00e8da9b title A Love Supreme sku_00e8da9b … … … …

sku_00e8da9b 아티스트 John Coltrane

sku_00e8da9b 장르

… gnoDB는 관계형 데이터베이스와 다르며 스키마가 없으며 문서 내용을 변경할 수 있습니다. 매우 유연하게 사용자 정의할 수 있습니다. 요구 사항: 컬렉션에 제품 정보를 저장하고 컬렉션의 다양한 제품에 대해 문서 콘텐츠를 사용자 정의할 수 있습니다.

예를 들어 음악 앨범은

{
  sku: "00e8da9b",
  type: "Audio Album",
  title: "A Love Supreme",
  description: "by John Coltrane",
  asin: "B0000A118M",
  shipping: {
    weight: 6,
    dimensions: {
      width: 10,
      height: 10,
      depth: 1
    },
  },
  pricing: {
    list: 1200,
    retail: 1100,
    savings: 100,
    pct_savings: 8
  },
  details: {
    title: "A Love Supreme [Original Recording Reissued]",
    artist: "John Coltrane",
    genre: [ "Jazz", "General" ],
        ...
    tracks: [
      "A Love Supreme Part I: Acknowledgement",
      "A Love Supreme Part II - Resolution",
      "A Love Supreme, Part III: Pursuance",
      "A Love Supreme, Part IV-Psalm"
    ],
  },
}

와 유사한 문서 구조를 가질 수 있고, 영화는

로 저장할 수 있습니다.
{
  sku: "00e8da9d",
  type: "Film",
  ...,
  asin: "B000P0J0AQ",
  shipping: { ... },
  pricing: { ... },
  details: {
    title: "The Matrix",
    director: [ "Andy Wachowski", "Larry Wachowski" ],
    writer: [ "Andy Wachowski", "Larry Wachowski" ],
    ...,
    aspect_ratio: "1.66:1"
  },
}

所有商品都拥有一些共同的基本信息,特定的商品可以根据需要扩展独有的内容,非常方便; 基于上述模型,MongoDB 也能很好的服务各类查询。

查询某个演员参演的所有电影,并按发型日志排序

db.products.find({'type': 'Film', 'details.actor': 'Keanu Reeves'}).sort({'details.issue_date', -1})

上述查询也可以通过建立索引来加速

db.products.createIndex({ type: 1, 'details.actor': 1, 'details.issue_date': -1 })

查询标题里包含特定信息的所有电影

db.products.find({
    'type': 'Film',
    'title': {'$regex': '.*hacker.*', '$options':'i'}}).sort({'details.issue_date', -1})

可建立如下索引来加速查询

db.products.createIndex({ type: 1, details.issue_date: -1, title: 1 })

扩展

当单个节点无法满足海量商品信息存储的需求时,就需要使用MongoDB sharding来扩展,假定大量的查询都是都会基于商品类型,那么就可以使用商品类型字段来进行分片。

db.shardCollection('products', { key: {type: 1} })

分片时,尽量使用复合的索引字段,这样能满足更多的查询需求,比如基于商品类型之后,还会经常根据商品的风格标签来查询,则可以把商品的标签字段作为第二分片key。

db.shardCollection('products', { key: {type: 1, 'details.genre': 1} })

如果某种类型的商品,拥有相同标签的特别多,则会出现jumbo chunk的问题,导致无法迁移,可以进一步的优化分片key,以避免这种情况。

db.shardCollection('products', { key: {type: 1, 'details.genre': 1, sku: 1} })

加入第3分片key之后,即使类型、风格标签都相同,但其sku信息肯定不同,就肯定不会出现超大的chunk。


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.