๊ธฐ๋Šฅ์„ฑ DBMS

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ธ๊ณ„๋Š” ์˜ค๋žซ๋™์•ˆ SQL ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ด€๊ณ„ํ˜• DBMS๊ฐ€ ์ง€๋ฐฐํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ƒˆ๋กœ์šด ๋ณ€์ข…์„ NoSQL์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ด ์‹œ์žฅ์—์„œ ์Šค์Šค๋กœ ํŠน์ • ์œ„์น˜๋ฅผ ๊ฐœ์ฒ™ํ–ˆ์ง€๋งŒ ๊ด€๊ณ„ํ˜• DBMS๋Š” ์ฃฝ์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ ๊ณ„์†ํ•ด์„œ ๊ทธ๋“ค์˜ ๋ชฉ์ ์„ ์œ„ํ•ด ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๊ธฐ๋Šฅ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฐœ๋…์„ ์„ค๋ช…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋” ๋‚˜์€ ์ดํ•ด๋ฅผ ์œ„ํ•ด ์ด๋ฅผ ๊ณ ์ „์ ์ธ ๊ด€๊ณ„ํ˜• ๋ชจ๋ธ๊ณผ ๋น„๊ตํ•˜์—ฌ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐ๋„ท์—์„œ ๋ฐœ๊ฒฌ๋œ ๊ฐ์ข… SQL ํ…Œ์ŠคํŠธ์˜ ๋ฌธ์ œ์ ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์†Œ๊ฐœ

๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ํ…Œ์ด๋ธ”๊ณผ ํ•„๋“œ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜๊ฐ€ ๊ฐ๊ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. N๊ฐœ ํ‚ค๊ฐ€ ์žˆ๋Š” ํ…Œ์ด๋ธ”์˜ ํ•„๋“œ๋Š” N๊ฐœ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํ•จ์ˆ˜๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ” ๊ฐ„์˜ ๊ด€๊ณ„ ๋Œ€์‹  ์—ฐ๊ฒฐ์ด ์ด๋ฃจ์–ด์ง„ ํด๋ž˜์Šค์˜ ๊ฐœ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. JOIN ๋Œ€์‹  ํ•จ์ˆ˜ ํ•ฉ์„ฑ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ž‘์—…์œผ๋กœ ๋ฐ”๋กœ ์ด๋™ํ•˜๊ธฐ ์ „์— ๋„๋ฉ”์ธ ๋กœ์ง ์ž‘์—…์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. DDL์˜ ๊ฒฝ์šฐ PostgreSQL ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ ์œผ๋กœ๋Š” ์ž์ฒด ๊ตฌ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ด๋ธ” ๋ฐ ํ•„๋“œ

์ด๋ฆ„ ๋ฐ ๊ฐ€๊ฒฉ ํ•„๋“œ๊ฐ€ ์žˆ๋Š” ๊ฐ„๋‹จํ•œ Sku ๊ฐœ์ฒด:

๊ด€๊ณ„ํ˜•

CREATE TABLE Sku
(
    id bigint NOT NULL,
    name character varying(100),
    price numeric(10,5),
    CONSTRAINT id_pkey PRIMARY KEY (id)
)

๊ธฐ๋Šฅ์˜

CLASS Sku;
name = DATA STRING[100] (Sku);
price = DATA NUMERIC[10,5] (Sku);

XNUMX๊ฐœ๋ฅผ ๋ฐœํ‘œํ•ฉ๋‹ˆ๋‹ค ๊ธฐ๋Šฅ, ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ Sku๋ฅผ ์ž…๋ ฅ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ๊ธฐ๋ณธ ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ์  DBMS์—์„œ๋Š” ๊ฐ ๊ฐœ์ฒด์— ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๊ณ  ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ œํ’ˆ/๋งค์žฅ/๊ณต๊ธ‰์—…์ฒด์˜ ๊ฐ€๊ฒฉ์„ ์„ค์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ…Œ์ด๋ธ”์— ์‹œ๊ฐ„ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋‹จ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋Œ€ํ•œ ํ…Œ์ด๋ธ” ์„ ์–ธ์„ ๊ฑด๋„ˆ๋›ฐ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ด€๊ณ„ํ˜•

CREATE TABLE prices
(
    skuId bigint NOT NULL,
    storeId bigint NOT NULL,
    supplierId bigint NOT NULL,
    dateTime timestamp without time zone,
    price numeric(10,5),
    CONSTRAINT prices_pkey PRIMARY KEY (skuId, storeId, supplierId)
)

๊ธฐ๋Šฅ์˜

CLASS Sku;
CLASS Store;
CLASS Supplier;
dateTime = DATA DATETIME (Sku, Store, Supplier);
price = DATA NUMERIC[10,5] (Sku, Store, Supplier);

์ง€์ˆ˜

๋งˆ์ง€๋ง‰ ์˜ˆ์—์„œ๋Š” ํŠน์ • ์‹œ๊ฐ„์˜ ๊ฐ€๊ฒฉ์„ ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋“  ํ‚ค์™€ ๋‚ ์งœ์— ๋Œ€ํ•œ ์ธ๋ฑ์Šค๋ฅผ ๊ตฌ์ถ•ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ด€๊ณ„ํ˜•

CREATE INDEX prices_date
    ON prices
    (skuId, storeId, supplierId, dateTime)

๊ธฐ๋Šฅ์˜

INDEX Sku sk, Store st, Supplier sp, dateTime(sk, st, sp);

์ž‘์—…

ํ•ด๋‹นํ•˜๋Š” ๋น„๊ต์  ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์กฐํ•ญ ํ•˜๋ธŒ๋ฅด์—์„œ.

๋จผ์ € ๋„๋ฉ”์ธ ๋…ผ๋ฆฌ๋ฅผ ์„ ์–ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฒฝ์šฐ ์œ„ ๋ฌธ์„œ์—์„œ ์ง์ ‘ ์ˆ˜ํ–‰๋จ).

CLASS Department;
name = DATA STRING[100] (Department);

CLASS Employee;
department = DATA Department (Employee);
chief = DATA Employee (Employee);
name = DATA STRING[100] (Employee);
salary = DATA NUMERIC[14,2] (Employee);

1.1 ์ž‘์—…

์ง์† ์ƒ์‚ฌ๋ณด๋‹ค ๋” ๋งŽ์€ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์›์˜ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜์‹ญ์‹œ์˜ค.

๊ด€๊ณ„ํ˜•

select a.*
from   employee a, employee b
where  b.id = a.chief_id
and    a.salary > b.salary

๊ธฐ๋Šฅ์˜

SELECT name(Employee a) WHERE salary(a) > salary(chief(a));

1.2 ์ž‘์—…

ํ•ด๋‹น ๋ถ€์„œ์—์„œ ์ตœ๋Œ€ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์›์„ ๋‚˜์—ดํ•˜์„ธ์š”.

๊ด€๊ณ„ํ˜•

select a.*
from   employee a
where  a.salary = ( select max(salary) from employee b
                    where  b.department_id = a.department_id )

๊ธฐ๋Šฅ์˜

maxSalary 'ะœะฐะบัะธะผะฐะปัŒะฝะฐั ะทะฐั€ะฟะปะฐั‚ะฐ' (Department s) = 
    GROUP MAX salary(Employee e) IF department(e) = s;
SELECT name(Employee a) WHERE salary(a) = maxSalary(department(a));

// ะธะปะธ ะตัะปะธ "ะทะฐะธะฝะปะฐะนะฝะธั‚ัŒ"
SELECT name(Employee a) WHERE 
    salary(a) = maxSalary(GROUP MAX salary(Employee e) IF department(e) = department(a));

๋‘ ๊ตฌํ˜„ ๋ชจ๋‘ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ, ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ CREATE VIEW๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ๋จผ์ € ํŠน์ • ๋ถ€์„œ์˜ ์ตœ๋Œ€ ๊ธ‰์—ฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์—์„œ๋Š” ๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด ์†”๋ฃจ์…˜์„ ๋” ์ž˜ ๋ฐ˜์˜ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์‚ฌ๋ก€๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1.3 ์ž‘์—…

๋ถ€์„œ ID, ์ง์› ์ˆ˜๊ฐ€ 3๋ช…์„ ์ดˆ๊ณผํ•˜์ง€ ์•Š๋Š” ๋ชฉ๋ก์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„ํ˜•

select department_id
from   employee
group  by department_id
having count(*) <= 3

๊ธฐ๋Šฅ์˜

countEmployees 'ะšะพะปะธั‡ะตัั‚ะฒะพ ัะพั‚ั€ัƒะดะฝะธะบะพะฒ' (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
SELECT Department d WHERE countEmployees(d) <= 3;

1.4 ์ž‘์—…

๊ฐ™์€ ๋ถ€์„œ์— ๊ทผ๋ฌดํ•˜๋Š” ์ง€์ •๋œ ๊ด€๋ฆฌ์ž๊ฐ€ ์—†๋Š” ์ง์›์˜ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„ํ˜•

select a.*
from   employee a
left   join employee b on (b.id = a.chief_id and b.department_id = a.department_id)
where  b.id is null

๊ธฐ๋Šฅ์˜

SELECT name(Employee a) WHERE NOT (department(chief(a)) = department(a));

1.5 ์ž‘์—…

์ตœ๋Œ€ ์ด ์ง์› ๊ธ‰์—ฌ๊ฐ€ ํฌํ•จ๋œ ๋ถ€์„œ ID ๋ชฉ๋ก์„ ์ฐพ์Šต๋‹ˆ๋‹ค.

๊ด€๊ณ„ํ˜•

with sum_salary as
  ( select department_id, sum(salary) salary
    from   employee
    group  by department_id )
select department_id
from   sum_salary a       
where  a.salary = ( select max(salary) from sum_salary )

๊ธฐ๋Šฅ์˜

salarySum 'ะœะฐะบัะธะผะฐะปัŒะฝะฐั ะทะฐั€ะฟะปะฐั‚ะฐ' (Department d) = 
    GROUP SUM salary(Employee e) IF department(e) = d;
maxSalarySum 'ะœะฐะบัะธะผะฐะปัŒะฝะฐั ะทะฐั€ะฟะปะฐั‚ะฐ ะพั‚ะดะตะปะพะฒ' () = 
    GROUP MAX salarySum(Department d);
SELECT Department d WHERE salarySum(d) = maxSalarySum();

๋‹ค๋ฅธ ์ž‘์—…์—์„œ ๋” ๋ณต์žกํ•œ ์ž‘์—…์œผ๋กœ ๋„˜์–ด ๊ฐ‘์‹œ๋‹ค ์กฐํ•ญ. ์—ฌ๊ธฐ์—๋Š” MS SQL์—์„œ ์ด ์ž‘์—…์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋ถ„์„์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

2.1 ์ž‘์—…

1997๋…„์— 30๋ฒˆ ์ œํ’ˆ์„ 1๊ฐœ ์ด์ƒ ํŒ๋งคํ•œ ํŒ๋งค์ž๋Š” ๋ˆ„๊ตฌ์ž…๋‹ˆ๊นŒ?

๋„๋ฉ”์ธ ๋กœ์ง(์ด์ „ RDBMS์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์„ ์–ธ์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค):

CLASS Employee 'ะŸั€ะพะดะฐะฒะตั†';
lastName 'ะคะฐะผะธะปะธั' = DATA STRING[100] (Employee);

CLASS Product 'ะŸั€ะพะดัƒะบั‚';
id = DATA INTEGER (Product);
name = DATA STRING[100] (Product);

CLASS Order 'ะ—ะฐะบะฐะท';
date = DATA DATE (Order);
employee = DATA Employee (Order);

CLASS Detail 'ะกั‚ั€ะพะบะฐ ะทะฐะบะฐะทะฐ';

order = DATA Order (Detail);
product = DATA Product (Detail);
quantity = DATA NUMERIC[10,5] (Detail);

๊ด€๊ณ„ํ˜•

select LastName
from Employees as e
where (
  select sum(od.Quantity)
  from [Order Details] as od
  where od.ProductID = 1 and od.OrderID in (
    select o.OrderID
    from Orders as o
    where year(o.OrderDate) = 1997 and e.EmployeeID = o.EmployeeID)
) > 30

๊ธฐ๋Šฅ์˜

sold (Employee e, INTEGER productId, INTEGER year) = 
    GROUP SUM quantity(OrderDetail d) IF 
        employee(order(d)) = e AND 
        id(product(d)) = productId AND 
        extractYear(date(order(d))) = year;
SELECT lastName(Employee e) WHERE sold(e, 1, 1997) > 30;

2.2 ์ž‘์—…

๊ฐ ๊ตฌ๋งค์ž(์ด๋ฆ„, ์„ฑ)์— ๋Œ€ํ•ด ๊ตฌ๋งค์ž๊ฐ€ 1997๋…„์— ๊ฐ€์žฅ ๋งŽ์€ ๋ˆ์„ ์ง€์ถœํ•œ ๋‘ ๊ฐ€์ง€ ์ƒํ’ˆ(์ด๋ฆ„)์„ ์ฐพ์œผ์‹ญ์‹œ์˜ค.

์ด์ „ ์˜ˆ์—์„œ ๋„๋ฉ”์ธ ๋…ผ๋ฆฌ๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.

CLASS Customer 'ะšะปะธะตะฝั‚';
contactName 'ะคะ˜ะž' = DATA STRING[100] (Customer);

customer = DATA Customer (Order);

unitPrice = DATA NUMERIC[14,2] (Detail);
discount = DATA NUMERIC[6,2] (Detail);

๊ด€๊ณ„ํ˜•

SELECT ContactName, ProductName FROM (
SELECT c.ContactName, p.ProductName
, ROW_NUMBER() OVER (
    PARTITION BY c.ContactName
    ORDER BY SUM(od.Quantity * od.UnitPrice * (1 - od.Discount)) DESC
) AS RatingByAmt
FROM Customers c
JOIN Orders o ON o.CustomerID = c.CustomerID
JOIN [Order Details] od ON od.OrderID = o.OrderID
JOIN Products p ON p.ProductID = od.ProductID
WHERE YEAR(o.OrderDate) = 1997
GROUP BY c.ContactName, p.ProductName
) t
WHERE RatingByAmt < 3

๊ธฐ๋Šฅ์˜

sum (Detail d) = quantity(d) * unitPrice(d) * (1 - discount(d));
bought 'ะšัƒะฟะธะป' (Customer c, Product p, INTEGER y) = 
    GROUP SUM sum(Detail d) IF 
        customer(order(d)) = c AND 
        product(d) = p AND 
        extractYear(date(order(d))) = y;
rating 'ะ ะตะนั‚ะธะฝะณ' (Customer c, Product p, INTEGER y) = 
    PARTITION SUM 1 ORDER DESC bought(c, p, y), p BY c, y;
SELECT contactName(Customer c), name(Product p) WHERE rating(c, p, 1997) < 3;

PARTITION ์—ฐ์‚ฐ์ž๋Š” ๋‹ค์Œ ์›์น™์— ๋”ฐ๋ผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ง€์ •๋œ ๊ทธ๋ฃน(์—ฌ๊ธฐ์„œ๋Š” Customer ๋ฐ Year, ๊ทธ๋Ÿฌ๋‚˜ ์ž„์˜์˜ ํ‘œํ˜„์‹์ผ ์ˆ˜ ์žˆ์Œ) ๋‚ด์—์„œ SUM(์—ฌ๊ธฐ์„œ๋Š” 1) ๋‹ค์Œ์— ์ง€์ •๋œ ํ‘œํ˜„์‹์„ ํ•ฉ์‚ฐํ•˜๊ณ  ๊ทธ๋ฃน ๋‚ด์—์„œ๋Š” ORDER( ์—ฌ๊ธฐ์—์„œ ๊ตฌ๋งคํ–ˆ์œผ๋ฉฐ, ๋™์ผํ•˜๋‹ค๋ฉด ๋‚ด๋ถ€ ์ œํ’ˆ ์ฝ”๋“œ์— ๋”ฐ๋ผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.)

2.3 ์ž‘์—…

ํ˜„์žฌ ์ฃผ๋ฌธ์„ ์ดํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ณต๊ธ‰์—…์ฒด๋กœ๋ถ€ํ„ฐ ์ฃผ๋ฌธํ•ด์•ผ ํ•˜๋Š” ์ƒํ’ˆ ์ˆ˜์ž…๋‹ˆ๋‹ค.

๋„๋ฉ”์ธ ๋กœ์ง์„ ๋‹ค์‹œ ํ™•์žฅํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

CLASS Supplier 'ะŸะพัั‚ะฐะฒั‰ะธะบ';
companyName = DATA STRING[100] (Supplier);

supplier = DATA Supplier (Product);

unitsInStock 'ะžัั‚ะฐั‚ะพะบ ะฝะฐ ัะบะปะฐะดะต' = DATA NUMERIC[10,3] (Product);
reorderLevel 'ะะพั€ะผะฐ ะฟั€ะพะดะฐะถะธ' = DATA NUMERIC[10,3] (Product);

๊ด€๊ณ„ํ˜•

select s.CompanyName, p.ProductName, sum(od.Quantity) + p.ReorderLevel โ€” p.UnitsInStock as ToOrder
from Orders o
join [Order Details] od on o.OrderID = od.OrderID
join Products p on od.ProductID = p.ProductID
join Suppliers s on p.SupplierID = s.SupplierID
where o.ShippedDate is null
group by s.CompanyName, p.ProductName, p.UnitsInStock, p.ReorderLevel
having p.UnitsInStock < sum(od.Quantity) + p.ReorderLevel

๊ธฐ๋Šฅ์˜

orderedNotShipped 'ะ—ะฐะบะฐะทะฐะฝะพ, ะฝะพ ะฝะต ะพั‚ะณั€ัƒะถะตะฝะพ' (Product p) = 
    GROUP SUM quantity(OrderDetail d) IF product(d) = p;
toOrder 'ะš ะทะฐะบะฐะทัƒ' (Product p) = orderedNotShipped(p) + reorderLevel(p) - unitsInStock(p);
SELECT companyName(supplier(Product p)), name(p), toOrder(p) WHERE toOrder(p) > 0;

๋ณ„ํ‘œ ๋ฌธ์ œ

๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ์˜ˆ๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์ œ๊ฐ€ ๋งŒ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์†Œ์…œ ๋„คํŠธ์›Œํฌ์˜ ๋…ผ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ ์„œ๋กœ ์นœ๊ตฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ณ  ์„œ๋กœ ์ข‹์•„ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€์ ์—์„œ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

CLASS Person;
likes = DATA BOOLEAN (Person, Person);
friends = DATA BOOLEAN (Person, Person);

์šฐ์ •์„ ์Œ“์„ ์ˆ˜ ์žˆ๋Š” ํ›„๋ณด์ž๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ณด๋‹ค ๊ณต์‹์ ์œผ๋กœ, A๋Š” B์™€ ์นœ๊ตฌ์ด๊ณ , B๋Š” C์™€ ์นœ๊ตฌ์ด๊ณ , A๋Š” C๋ฅผ ์ข‹์•„ํ•˜์ง€๋งŒ A๋Š” C์™€ ์นœ๊ตฌ๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  A, B, C ์‚ฌ๋žŒ์„ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋Šฅ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€์ ์—์„œ ์ฟผ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

SELECT Person a, Person b, Person c WHERE 
    likes(a, c) AND NOT friends(a, c) AND 
    friends(a, b) AND friends(b, c);

๋…์ž๋Š” SQL์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ์Šค์Šค๋กœ ํ•ด๊ฒฐํ•˜๋„๋ก ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ์ข‹์•„ํ•˜๋Š” ์‚ฌ๋žŒ๋ณด๋‹ค ์นœ๊ตฌ๊ฐ€ ํ›จ์”ฌ ์ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณ„๋„์˜ ํ…Œ์ด๋ธ”์— ์žˆ์Šต๋‹ˆ๋‹ค. ์„ฑ๊ณตํ•˜๋ฉด ๋ณ„์ด ๋‘ ๊ฐœ ์žˆ๋Š” ์ž‘์—…๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์•ˆ์—์„œ ์šฐ์ •์€ ๋Œ€์นญ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

SELECT Person a, Person b, Person c WHERE 
    likes(a, c) AND NOT friends(a, c) AND 
    (friends(a, b) OR friends(b, a)) AND 
    (friends(b, c) OR friends(c, b));

UPD: ์ฒซ ๋ฒˆ์งธ ๋ฐ ๋‘ ๋ฒˆ์งธ ๋ณ„ํ‘œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜ dss_kalika:

SELECT 
   pl.PersonAID
  ,pf.PersonAID
  ,pff.PersonAID
FROM Persons                 AS p
--ะ›ะฐะนะบะธ                      
JOIN PersonRelationShip      AS pl ON pl.PersonAID = p.PersonID
                                  AND pl.Relation  = 'Like'
--ะ”ั€ัƒะทัŒั                     
JOIN PersonRelationShip      AS pf ON pf.PersonAID = p.PersonID 
                                  AND pf.Relation = 'Friend'
--ะ”ั€ัƒะทัŒั ะ”ั€ัƒะทะตะน              
JOIN PersonRelationShip      AS pff ON pff.PersonAID = pf.PersonBID
                                   AND pff.PersonBID = pl.PersonBID
                                   AND pff.Relation = 'Friend'
--ะ•ั‰ั‘ ะฝะต ะดั€ัƒะถะฐั‚         
LEFT JOIN PersonRelationShip AS pnf ON pnf.PersonAID = p.PersonID
                                   AND pnf.PersonBID = pff.PersonBID
                                   AND pnf.Relation = 'Friend'
WHERE pnf.PersonAID IS NULL 

;WITH PersonRelationShipCollapsed AS (
  SELECT pl.PersonAID
        ,pl.PersonBID
        ,pl.Relation 
  FROM #PersonRelationShip      AS pl 
  
  UNION 

  SELECT pl.PersonBID AS PersonAID
        ,pl.PersonAID AS PersonBID
        ,pl.Relation
  FROM #PersonRelationShip      AS pl 
)
SELECT 
   pl.PersonAID
  ,pf.PersonBID
  ,pff.PersonBID
FROM #Persons                      AS p
--ะ›ะฐะนะบะธ                      
JOIN PersonRelationShipCollapsed  AS pl ON pl.PersonAID = p.PersonID
                                 AND pl.Relation  = 'Like'                                  
--ะ”ั€ัƒะทัŒั                          
JOIN PersonRelationShipCollapsed  AS pf ON pf.PersonAID = p.PersonID 
                                 AND pf.Relation = 'Friend'
--ะ”ั€ัƒะทัŒั ะ”ั€ัƒะทะตะน                   
JOIN PersonRelationShipCollapsed  AS pff ON pff.PersonAID = pf.PersonBID
                                 AND pff.PersonBID = pl.PersonBID
                                 AND pff.Relation = 'Friend'
--ะ•ั‰ั‘ ะฝะต ะดั€ัƒะถะฐั‚                   
LEFT JOIN PersonRelationShipCollapsed AS pnf ON pnf.PersonAID = p.PersonID
                                   AND pnf.PersonBID = pff.PersonBID
                                   AND pnf.Relation = 'Friend'
WHERE pnf.[PersonAID] IS NULL 

๊ฒฐ๋ก 

์ฃผ์–ด์ง„ ์–ธ์–ด ๊ตฌ๋ฌธ์€ ์ฃผ์–ด์ง„ ๊ฐœ๋…์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜์ผ ๋ฟ์ด๋ผ๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. SQL์„ ๊ธฐ๋ณธ์œผ๋กœ ์‚ผ์•˜๊ณ , ์ตœ๋Œ€ํ•œ ์œ ์‚ฌํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์˜€์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ํ‚ค์›Œ๋“œ ์ด๋ฆ„, ๋‹จ์–ด ๋ ˆ์ง€์Šคํ„ฐ ๋“ฑ์ด ๋งˆ์Œ์— ๋“ค์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๊ฐœ๋… ์ž์ฒด์ž…๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ C++์™€ Python์„ ๋ชจ๋‘ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ ์ƒ๊ฐ์—๋Š” ์„ค๋ช…๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐœ๋…์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํŽธํ•จ. ์ด๋Š” ๋‹จ์ˆœํ•œ ๊ฒฝ์šฐ์—๋Š” ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ์ƒ๋Œ€์ ์œผ๋กœ ์ฃผ๊ด€์ ์ธ ์ง€ํ‘œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋” ๋ณต์žกํ•œ ์‚ฌ๋ก€(์˜ˆ: ๋ณ„ํ‘œ ๊ด€๋ จ ๋ฌธ์ œ)๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์ด๋Ÿฌํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
  • ะ˜ะฝะบะฐะฟััƒะปัั†ะธั. ์ผ๋ถ€ ์˜ˆ์—์„œ๋Š” ์ค‘๊ฐ„ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ–ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ํŒ๋งค, ๊ตฌ์ž… ๋“ฑ), ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํ›„์† ๊ธฐ๋Šฅ์ด ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ•ด๋‹น ๊ธฐ๋Šฅ์— ์˜์กดํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ๋…ผ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ํŠน์ • ๊ธฐ๋Šฅ์˜ ๋…ผ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํŒ๋งค๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒ๋งค ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ฐœ์ฒด์—์„œ ๊ณ„์‚ฐ๋˜์—ˆ์ง€๋งŒ ๋‚˜๋จธ์ง€ ๋…ผ๋ฆฌ๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ, CREATE VIEW๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ RDBMS์—์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๋…ผ๋ฆฌ๊ฐ€ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑ๋˜๋ฉด ์ฝ๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์˜๋ฏธ์ƒ์˜ ๊ณต๋ฐฑ ์—†์Œ. ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ํ…Œ์ด๋ธ”๊ณผ ํ•„๋“œ ๋Œ€์‹  ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ณ ์ „ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(๋ฉ”์„œ๋“œ๊ฐ€ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ํ˜•ํƒœ๋กœ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ–๋Š” ํ•จ์ˆ˜๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒฝ์šฐ). ๋”ฐ๋ผ์„œ ๋ฒ”์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์™€ "์นœ๊ตฌ๋ฅผ ์‚ฌ๊ท€๋Š”" ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๋” ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ฐ์‚ฐ์ž๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    CONSTRAINT sold(Employee e, 1, 2019) > 100 IF name(e) = 'ะŸะตั‚ั' MESSAGE  'ะงั‚ะพ-ั‚ะพ ะŸะตั‚ั ะฟั€ะพะดะฐะตั‚ ัะปะธัˆะบะพะผ ะผะฝะพะณะพ ะพะดะฝะพะณะพ ั‚ะพะฒะฐั€ะฐ ะฒ 2019 ะณะพะดัƒ';

  • ์ƒ์†๊ณผ ๋‹คํ˜•์„ฑ. ๊ธฐ๋Šฅ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” CLASS ClassP: Class1, Class2 ๊ตฌ์„ฑ์„ ํ†ตํ•ด ๋‹ค์ค‘ ์ƒ์†์„ ๋„์ž…ํ•˜๊ณ  ๋‹ค์ค‘ ๋‹คํ˜•์„ฑ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•„๋งˆ๋„ ํ–ฅํ›„ ๊ธฐ์‚ฌ์—์„œ ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ์“ฐ๋Š”์ง€ ์“ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‹จ์ง€ ๊ฐœ๋…์ผ ๋ฟ์ด์ง€๋งŒ ๋ชจ๋“  ๊ธฐ๋Šฅ์  ๋…ผ๋ฆฌ๋ฅผ ๊ด€๊ณ„ํ˜• ๋…ผ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” Java ๊ตฌํ˜„์ด ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ‘œํ˜„์˜ ๋…ผ๋ฆฌ์™€ ๊ธฐํƒ€ ๋งŽ์€ ๊ฒƒ๋“ค์ด ์•„๋ฆ„๋‹ต๊ฒŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ์ „์ฒด๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ํ”Œ๋žซํผ. ๊ธฐ๋ณธ์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” RDBMS(ํ˜„์žฌ๋Š” PostgreSQL๋งŒ)๋ฅผ "๊ฐ€์ƒ ๋จธ์‹ "์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. FDBMS๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ํŠน์ • ํ†ต๊ณ„๋ฅผ RDBMS ์ฟผ๋ฆฌ ์ตœ์ ํ™” ํ”„๋กœ๊ทธ๋žจ์ด ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ณ€ํ™˜์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ก ์ ์œผ๋กœ๋Š” ๊ธฐ๋Šฅ์  ๋…ผ๋ฆฌ์— ๋งž๊ฒŒ ํŠน๋ณ„ํžˆ ์กฐ์ •๋œ ํŠน์ • ๊ตฌ์กฐ๋ฅผ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€