了解SustrealQl及其与PostgreSQL有何不同
#初学者 #postgres #database #surrealdb

PostgreSQL已经存在了一段时间,并且是需要可靠性,性能和可伸缩性的应用程序的首选。这是许多大公司和初创公司使用的开源,SQL数据库,从Web应用到科学研究。但是,随着需要构建更复杂的应用程序,传统SQL数据库的局限性正在显示。开发人员与Postgres提出的主要问题之一是编写复杂的连接。对于经验丰富的SQL程序员来说,这甚至很棘手。

SurreAldB及其历史简介

SurreAldB具有一种名为SurtealQl的SQL风格的查询语言,它是一种功能强大的数据库查询语言,非常类似于传统的SQL,但有略有差异和改进。
在本文中,我们将探讨PostgreSQL和SertealQl之间的相似性和差异。我们还将看到SurrealQl如何克服关系数据库的某些局限性。将其视为具有PostgreSQL背景的每个开发人员的指南,以更好地理解SertealQL,而不是逐步的教程。

在开始之前,这是您应该了解的一些基本概念。

您可以使用SELECTCREATEUPDATEDELETERELATEINSERT语句来查询和操纵surseAldB中的数据。您还可以使用dot notation.,数组符号[]和图语义 - >。

检索数据。

surstealql允许记录链接到其他记录,并根据需要在所有嵌入式链接或图形连接上行驶。

您可以阅读更多有关它的信息。

建立电子商务平台

在此博客中,我们将研究一个使用PostgreSQL和SurtealQl并排构建的电子商务平台。

电子商务应用程序需要一种特殊的架构,可以处理产品变化,定价层和客户详细信息。虽然可以使用关系数据库成功构建电子商务数据库,但架构可以使用许多表和加入以维护交易数据很复杂。

以下是我们将要构建的轻型电子商务平台的关系模式。我们的平台只有3个客户和几个产品的范围有限,因此我们可以专注于每个查询,并将其与SurtealQl进行比较以了解其不同。

PostgreSQL schema of an E-commerce platform

数据操纵和查询

这就是我们在postgresql vs sursealdb中的表中的INSERT数据。

使用SELECT,创建,更新和删除语句的SurrealQl中数据的操作和查询。这些启用选择或修改单个记录或整表。每个语句一次支持多个不同的表或记录类型。

postgresql

INSERT INTO product
    (name, description, price, category, images, options)
    VALUES
    ("Shirt", "Slim fit", 6, "clothing", ARRAY["image1.jpg", "image2.jpg", "image3.jpg"])
;

超级Ql

CREATE product CONTENT {
    name: 'Shirt',
    id: 'shirt',
    description: 'Slim fit', 
    price: 6, 
    category: 'clothing',  
    images: ['image1.jpg', 'image2.jpg', 'image3.jpg']
};

如果您要以严格的架构方法使用SursteAldB,则可以定义类似于PostgreSQL的模式。您可以在sursealdb here中找到定义表的详细说明。

但是,在示意图的方法中,您还可以选择快速入门而无需定义每一列。在SurreAldB中,我们可以直接定义实体之间的关系。我们不需要了解外键,我们也不必写有关如何存储它们的逻辑。

用于剩余表的后格雷斯克图架。

我们需要更多表来存储有关我们的电子商务数据库的元数据。这些表不需要SurreAldB中,因为我们遵循vertex-> edge-> vertexnoun-> verb-> noun justiment otary储存元数据。

-- Product Table.
CREATE TABLE product ( 
    id SERIAL PRIMARY KEY, 
    name TEXT, 
    description TEXT, 
    price NUMERIC(8,2), 
    category TEXT, 
    images TEXT[] 
);

-- Customer's Address.
CREATE TABLE address (
    address_id INT PRIMARY KEY,
    address_line_1 VARCHAR(255),
    address_line_2 VARCHAR(255),
    city VARCHAR(255),
    state VARCHAR(255),
    zip_code VARCHAR(255),
    country VARCHAR(255)
);

-- Customer Table.
CREATE TABLE customer (
    customer_id INT PRIMARY KEY,
    name VARCHAR(255),
    email VARCHAR(255),
    address_id INT,
    FOREIGN KEY (address_id) REFERENCES address(address_id)
);

-- Order details
CREATE TABLE customer_order (
    order_id INT PRIMARY KEY,
    customer_id INT,
    shipping_address_id INT,
    total_amount DECIMAL(10,2),
    FOREIGN KEY (customer_id) REFERENCES customer(customer_id),
    FOREIGN KEY (shipping_address_id) REFERENCES address(address_id)
);

-- Product details in an order
CREATE TABLE order_item (
    order_item_id INT PRIMARY KEY,
    order_id INT,
    product_id INT,
    quantity INT,
    price DECIMAL(10,2),
    FOREIGN KEY (order_id) REFERENCES customer_order(order_id),
    FOREIGN KEY (product_id) REFERENCES product(id)
);

让我们填充数据库

SuretealQL中的插入语句与Postgres中使用的插入语句相似。但是,SuretealQL具有一个更新语句,可以完成与Postgres的Alter语句相同的工作。此外,您可以在不更改架构的情况下轻松添加数据和列,这可能是可能的,因为SurreAldB可以作为模式或示意性结构发挥作用。在此特定示例中,我们遵循一种示意性方法,这意味着添加一列不会改变电子商务平台的基础架构。

让我们在产品表中添加一个选项列。

postgresql

ALTER TABLE product ADD COLUMN options jsonb[];

INSERT INTO product
    (name, description, price, category, images, options)
    VALUES
    (
        'Shirt', 'Slim fit', 6, 'clothing',
        ARRAY['image1.jpg', 'image2.jpg', 'image3.jpg'],
        ARRAY['{"sizes": ["S", "M", "L"]}', '{"colours": ["Red", "Blue", "Green"]}']::jsonb[]
    )
;

超级Ql

INSERT INTO product {
    name: 'Shirt',
    id: 'shirt', 
    description: 'Slim fit',
    price: 6, 
    category: 'clothing', 
    images: ['image1.jpg', 'image2.jpg', 'image3.jpg'],
    options: [
        { sizes: ['S', 'M', 'L'] }, 
        { colours: ['Red', 'Blue', 'Green'] }
    ] 
};

在我们开始查询电子商务数据库之前,让我们首先在PostgreSQL参考表中输入一些数据。

INSERT INTO address (address_id, address_line_1, city, state, zip_code, country)
VALUES (1, '123 Main St', 'New York', 'NY', '10001', 'USA');

INSERT INTO address (address_id, address_line_1, city, state, zip_code, country)
VALUES (2, '124 Main St', 'New York', 'NY', '10002', 'USA');

INSERT INTO address (address_id, address_line_1, city, state, zip_code, country)
VALUES (3, '125 Main St', 'New York', 'NY', '10003', 'USA');

INSERT INTO customer (customer_id, name, email, address_id)
VALUES (1, 'Tobie', 'tobie@gmail.com', 1);

INSERT INTO customer (customer_id, name, email, address_id)
VALUES(2, 'Alex', 'alex@example.com', 2);

INSERT INTO customer (customer_id, name, email, address_id)
VALUES (3, 'Pratim', 'pratim@example.com', 3);

INSERT INTO product (name, description, price, category, images, options)
VALUES ('Trousers', 'Pants', 10, 'clothing',
        ARRAY['image1.jpg', 'image2.jpg', 'image3.jpg'],
        ARRAY['{"sizes": ["S", "M", "L"]}', 
        '{"colours": ["Red", "Blue", "Green"]}']::jsonb[]);

INSERT INTO product (name, description, price, category, images, options)
VALUES ('Iphone', 'Mobile Phone', 600, 'Electronics',
        ARRAY['image1.jpg', 'image2.jpg', 'image3.jpg'],
        ARRAY['{"sizes": ["Max", "Pro", "SE"]}', 
                '{"colours": ["Red", "Blue", "Green"]}']::jsonb[]);

INSERT INTO customer_order (order_id, customer_id, shipping_address_id, total_amount)
VALUES (5, 3, 1, 600);

INSERT INTO order_item (order_item_id, order_id, product_id, quantity, price)
VALUES (6, 5, 1, 1, 600);

INSERT INTO order_item (order_item_id, order_id, product_id, quantity, price)
VALUES (7, 5, 3, 1, 600);

让我们也将一些数据也插入我们的SursteLDB表中!

INSERT INTO customer {
    name: 'Pratim',
    id: 'pratim',
    email: 'abc@gmail.com',
    address: { house_no: '221B', street: 'Baker street', city: 'London', country: 'UK' }
};

INSERT INTO customer {
    name: 'Tobie',
    id: 'tobie',
    email: 'tobie@gmail.com',
    address: { house_no: '221A', street: 'Church street', city: 'London', country: 'UK' }
};

INSERT INTO customer {
    name: 'Alex',
    id: 'alex',
    email: 'alex@gmail.com',
    address: { house_no: '221C', street: 'Pound street', city: 'London', country: 'UK' }
};

INSERT INTO product {
    name: 'Trousers',
    id: 'trousers',
    description: 'Pants',
    price: 10,
    category: 'clothing',
    images: ['image1.jpg', 'image2.jpg', 'image3.jpg'],
    options: [
        { sizes: ['S', 'M', 'L'] }, 
        { colours: ['Red', 'Blue', 'Green'] }
    ]
};

INSERT INTO product {
    name: 'Iphone',
    id: 'iphone',
    description: 'Mobile phone',
    price: 600,
    category: 'Electronics',
    images: ['image.jpg', 'image1.jpg', 'image4.jpg'],
    options: [
        { sizes: ['Max', 'Pro', 'SE'] },
        { colours: ['Red', 'Blue', 'Green'] }
    ]
};

检索数据

SurreDB中的选择语句与Postgres相似。

postgresql

SELECT * FROM product where id=1;

超级Ql

SELECT * FROM product:shirt;

SELECT语句将从产品表中获取所有必需的详细信息。在SursteAldB中,您可以为每个产品分配一个唯一的ID。如果您不为ID分配ID,则自动分配每个记录的唯一ID。在PostgreSQL中,这可以通过使用UUID列来实现,并且必须明确提及。

相关语句

相关语句可用于生成数据库中两个记录之间的图形边缘。图表代表了代表记录的两个节点之间的关系。
当客户购买产品时,SurreLdB使用“购买”关系将客户与产品联系起来。您可以将自己的关系命名,无论您认为正确是否正确。它也可以称为“购​​买”或“订购”。

RELATE customer:pratim->bought->product:iphone CONTENT {
    option: { Size: 'Max', Color: 'Red' },
    quantity: 1,
    total: 600,
    status: 'Pending',
    created_at: time::now()
};

RELATE customer:pratim->bought->product:shirt CONTENT {
    option: { Size: 'S', Color: 'Red' },
    quantity: 2,
    total: 40,
    status: 'Delivered',
    created_at: time::now()
};

RELATE customer:alex->bought->product:iphone CONTENT {
    option: { Size: 'M', Color: 'Max' }, 
    quantity: 1,
    total: 600,
    status: 'Pending',
    created_at: time::now()
};

RELATE customer:alex->bought->product:shirt CONTENT {
    option: { Size: 'S', Color: 'Red' },
    quantity: 2,
    total: 12,
    status: 'Delivered',
    created_at: time::now()
};

RELATE customer:tobie->bought->product:iphone CONTENT {
    option: { Size: 'M', Color: 'Max' }, 
    quantity: 1,
    total: 600,
    status: 'Pending',
    created_at: time::now()
};

让我们选择特定客户购买的所有产品

postgresql

SELECT p.id AS product_id, p.name AS product_name
FROM product p
JOIN order_item oi ON p.id = oi.product_id 
JOIN customer_order co ON oi.order_id = co.order_id 
JOIN customer c ON co.customer_id = c.customer_id
WHERE c.name = 'Pratim'
ORDER BY p.id;

超级Ql

SELECT * FROM customer:pratim->bought;

如果您注意到这是一个非常复杂的查询。 SurreAlDB中最强大的功能之一是能够使用图形连接和链接来关联记录的功能。 SurseLDB无需从多个表中获取数据并将这些数据合并在一起,而是允许您有效地选择相关记录而无需使用JONINS。

这是您发射上述超级Ql查询时得到的

[
    {
        "created_at": "2023-03-28T07:39:56.946636Z",
        "id": "bought:n88e3cuery13jfqhq4lh",
        "in": "customer:pratim",
        "option": {
            "Color": "Red",
            "Size": "S"
        },
        "out": "product:Shirt",
        "quantity": 2,
        "status": "Delivered",
        "total": 40
    },
    {
        "created_at": "2023-03-28T07:36:41.091383Z",
        "id": "bought:odadlqf1cv2970qvb8cx",
        "in": "customer:pratim",
        "option": {
            "Color": "Red",
            "Size": "Max"
        },
        "out": "product:Iphone",
        "quantity": 1,
        "status": "Pending",
        "total": 600
    }
]

您也可以在没有元数据的情况下直接获取产品ID。

SELECT out FROM customer:pratim->bought;
[
    {
        "out": "product:Shirt"
    },
    {
        "out": "product:Iphone"
    }
]

我们还可以查询图形bought

SELECT out FROM bought;
[
    {
        "out": "product:Shirt"
    },
    {
        "out": "product:Iphone"
    },
    {
        "out": "product:Iphone"
    },
    {
        "out": "product:Shirt"
    },
    {
        "out": "product:Iphone"
    }
]

如果您研究查询,您将意识到Pratim和Alex都购买了衬衫和iPhone。我们有一个新的客户Tobie,还购买了一件衬衫。您的电子商务系统想推荐其他客户购买的产品。

您将如何使用Postgres?

要根据Pratim和Alex购买的产品向Tobie推荐产品,我们首先需要找出Pratim和Alex购买了哪些产品,然后寻找其他购买了相同产品的客户。

此查询首先选择了Pratim和Alex购买的所有产品,然后滤除了Tobie已购买的产品。最终列表包括推荐给Tobie的项目的product_id和product_name。

SELECT DISTINCT p.id AS product_id, p.name AS product_name
FROM product p
JOIN order_item oi ON p.id = oi.product_id
JOIN customer_order co ON oi.order_id = co.order_id
JOIN customer c ON co.customer_id = c.customer_id
WHERE c.name IN ('Pratim', 'Alex') AND p.id NOT IN (
    SELECT p2.id
    FROM product p2
    JOIN order_item oi2 ON p2.id = oi2.product_id
    JOIN customer_order co2 ON oi2.order_id = co2.order_id
    JOIN customer c2 ON co2.customer_id = c2.customer_id
    WHERE c2.name = 'Tobie'
)
ORDER BY p.id;

你和我在一起还是你的头在旋转?让我们现在尝试在surrealql中执行此操作。

SELECT array::distinct(<-bought<-customer->bought->product.*) AS purchases
FROM product:shirt;
[
    {
        "purchases": [
            {
                "category": "clothing",
                "description": "Slim fit",
                "id": "product:shirt",
                "images": [
                    "image1.jpg",
                    "image2.jpg",
                    "image3.jpg"
                ],
                "name": "Shirt",
                "price": "6"
            },
            {
                "category": "Electronics",
                "description": "Mobile phone",
                "id": "product:iphone",
                "images": [
                    "image.jpg",
                    "image1.jpg",
                    "image4.jpg"
                ],
                "name": "Iphone",
                "options": [
                    {
                        "sizes": [
                            "Max",
                            "Pro",
                            "SE"
                        ]
                    },
                    {
                        "colours": [
                            "Red",
                            "Blue",
                            "Green"
                        ]
                    }
                ],
                "price": 600
            }
        ]
    }
]

在这里,我们正在从已购买衬衫的客户购买的各种产品中选择所有唯一价值。

但是,如果您不希望使用普通产品,即推荐衬衫怎么办?
您可以使用suretealql的SurrealQL operator NOTINSIDE来操纵数据。

SELECT array::distinct(<-bought<-customer->bought->(product WHERE id NOTINSIDE [product:shirt])) as products
FROM product:shirt;
[
    {
        "products": [
            "product:iphone"
        ]
    }
]

结论

在这篇博客文章中,我们看到了SurreAldB如何使您更容易与PostgreSQL相比,您可以更轻松地构建和查询数据库。借助SurseAldB,您可以真正拥有两个数据库中最好的,同时又不妥协安全性和灵活性。 SurseAldB具有许多功能,例如实时查询,具有高效相关的数据检索,用于多租户访问的高级安全权限,并支持提供性能分析工作负载。您可以阅读有关它们的更多信息here

下一步

如果您还没有从SursteLDB开始,则可以开始here。将您的问题放在我们的Discord上,不要忘记在GitHub上出演我们。