2011-03-15 40 views
5

Tiếp tục câu hỏi của tôi về EAV, tôi đang cân nhắc việc sử dụng MongoDB để lưu trữ các thuộc tính sản phẩm.Học thuyết ODM và thiết kế ít lược đồ

Tôi sẽ lưu trữ phần danh mục của ứng dụng này - Danh mục, Sản phẩm và tất cả thông tin liên quan của chúng - với MongoDB (hoặc cơ sở dữ liệu tài liệu khác).

Câu hỏi của tôi là, khi sử dụng ODM, mỗi thực thể có lược đồ, về cơ bản bỏ qua lợi thế ít lược đồ hơn khi sử dụng cơ sở dữ liệu NoSQL, phải không?

Nếu điều này đúng, tại sao mọi người sử dụng ODM?

EDIT: Tôi đã tìm thấy related question, tôi có thể đạt được chức năng thuộc tính sản phẩm bằng cách sử dụng hàm băm không?

Trả lời

5

Các giải pháp là sử dụng một @Hash

Dưới đây là một ví dụ rất cơ bản tôi đã làm lên:

<?php 

/** 
* @Document 
*/ 
class Product 
{ 

    /** 
    * @Id 
    */ 
    private $id; 

    /** 
    * @String 
    */ 
    private $name; 

    /** 
    * @Hash 
    */ 
    private $attributes = array(); 

    public function getId() 
    { 
     return $this->id; 
    } 

    public function setName($name) 
    { 
     $this->name = $name; 
    } 

    public function getName() 
    { 
     return $this->name; 
    } 

    public function addAttribute($name, $value) 
    { 
     $key = preg_replace('/[^a-z0-9\ \_]/i', '', $name); 
     $key = preg_replace('/\s+/i', '_', $key); 
     $key = strtolower($key); 
     $this->attributes[$key] = array('value' =>$value, 'label' => $name); 
    } 

    public function getAttribute($name) 
    { 
     return $this->attributes[$name]; 
    } 

    public function getAttributes() 
    { 
     return $this->attributes; 
    } 

} 

Thêm một số dữ liệu:

<?php 

$pen = new Product(); 
$pen->setName('Cool Pen'); 
$pen->addAttribute('Weight', 12); 
$pen->addAttribute('Ink Colour', 'Red'); 
$pen->addAttribute('Colour', 'Black'); 

$tv = new Product(); 
$tv->setName('LED LCD TV'); 
$tv->addAttribute('Weight', 12550); 
$tv->addAttribute('Screen Size', 32); 
$tv->addAttribute('Colour', 'Black'); 

$dm->persist($pen); 
$dm->persist($tv); 

$dm->flush(); 

Sau đó, truy vấn, tìm sản phẩm với màu "Đen" và Kích thước màn hình lớn hơn 20:

<?php 

$query = $dm->createQueryBuilder('Catalogue\Product'); 
$products = $query->field('attributes.colour.value')->equals('Black') 
       ->field('attributes.screen_size.value')->gte(20) 
       ->getQuery()->execute(); 

Tôi vẫn không chắc đây có phải là cách tốt nhất để làm điều này và nghiên cứu của tôi vẫn đang tiếp tục.

1

Mặc dù không có gì thực thi điều này, nhưng thực hành tốt là có một lược đồ cơ bản cho một bộ sưu tập. Hầu như tất cả ODM cho phép bạn thêm các trường không được chỉ định trong lớp. Giả sử ứng dụng cho phép nó, bạn cũng có thể bỏ qua các giá trị trường.

Lợi thế thực sự của kho dữ liệu schemaless, tuy nhiên, không quá nhiều trường cấp cao nhất của bạn có thể thay đổi tài liệu biểu mẫu thành tài liệu, nhưng các trường đó có thể là cấu trúc dữ liệu phức tạp. Mỗi sản phẩm có thể có và thuộc tính lĩnh vực đó là một mảng, nhưng nội dung của mảng đó có thể được tùy ý dài hay ngắn, và có thể chứa băm với các cấu trúc khác nhau. ODM của bạn nên thêm một lớp Object trên đầu trang của các băm nếu bạn yêu cầu nó.

Lợi thế cuối cùng là nâng cấp giản đồ. Trong SQL thêm hoặc loại bỏ một lĩnh vực là một hoạt động nguyên khối đó cũng là thời gian. Với quy hoạch nhỏ, bạn có thể thêm hoặc xóa các trường khỏi tài liệu khi chúng được truy cập. Bạn chỉ cần mã để xử lý lược đồ cũ.

Các vấn đề liên quan