Ein grundlegendes Funktionsmodul des E-Commerce-Geschäfts ist das Speichern von Produktinformationen mit umfangreichen Kategorien. Das flexible Dokumentmodell von MongoDB eignet sich hervorragend für diese Art von Geschäft um Produktklassifizierungen zu speichern.
Relationale Datenbanklösungen
Die oben genannten Probleme können auch mit herkömmlichen relationalen Datenbanken gelöst werden, wie zum Beispiel den folgenden Lösungen
Für Für verschiedene Produkte, erstellen Sie verschiedene Tabellen
Zum Beispiel haben zwei Produkte, Musikalben und Filme, einige gemeinsame Attribute, aber auch viele einzigartige Attribute. Sie können zwei verschiedene Tabellen mit unterschiedlichen Attributen erstellen.
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`)) ...
Das Hauptproblem bei diesem Ansatz besteht darin, dass
Für jede neue Produktkategorie eine neue Tabelle erstellt werden muss
Anwendungsentwickler müssen Anfragen zur Abfrage explizit an die entsprechenden Tabellen verteilen, was umständlich zu implementieren ist
Alle Produkte werden in einer einzigen Tabelle gespeichert
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`))
Speichern Sie alle Produkte in einer Tabelle. Diese Tabelle enthält die für alle Produkte erforderlichen Attribute. Diese Methode macht die Produktabfrage relativ einfach und ermöglicht, dass eine Abfrage mehrere Produkte umfasst ist, dass es viel Platz verschwendet.
Öffentliche Attribute extrahieren, Vererbung mehrerer Tabellen
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`)) ...
Das obige Schema extrahiert die gemeinsamen Attribute aller Produkte und speichert die gemeinsamen Attribute in einer Tabelle jedes Produkts erstellt eine neue Tabelle entsprechend seinen eigenen Anforderungen, und nur die für das Produkt eindeutigen Informationen werden in der neuen Tabelle gespeichert.
Entitätsattributwerte aus der Speicherung
Alle Daten werden in Form von 3-Tupeln gespeichert. Diese Lösung verwendet tatsächlich die relationale Datenbank als KV-Speicher, Modell Simple , aber für komplexe Abfragen nicht sehr praktisch.
ENTITÄT Typ Audioalbum sku_00e8da9b Titel A Love Supreme sku_00e8da9b … … … …
sku_00e8da9b Künstler John Coltrane
sku_00e8da9b Genre Allgemein
… Von relationalen Datenbanken hat es kein Schema, Dokumentinhalte können sein Es ist sehr flexibel anpassbar und kann den oben genannten Produktklassifizierungsspeicher gut nutzen. Anforderungen: Speichern Sie Produktinformationen in einer Sammlung, und der Dokumentinhalt kann für verschiedene Produkte in der Sammlung angepasst werden.
Zum Beispiel kann ein Musikalbum eine Dokumentstruktur ähnlich der folgenden haben:
, während ein Film alsgespeichert werden kann
{ 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。