Functional DBMS

Ny tontolon'ny angon-drakitra dia efa ela no nanjakan'ny relational DBMSs, izay mampiasa ny fiteny SQL. Hany ka ny variana mipoitra dia antsoina hoe NoSQL. Nahavita nanamboatra toerana iray ho an'ny tenany tao amin'ity tsena ity izy ireo, saingy tsy ho faty ny DBMS mifandraika, ary mbola ampiasaina amin'ny tanjony.

Amin'ity lahatsoratra ity dia te-hamariparitra ny foto-kevitry ny angon-drakitra miasa aho. Ho an'ny fahatakarana tsara kokoa dia hanao izany aho amin'ny fampitahana azy amin'ny modely relational klasika. Ny olana avy amin'ny fitsapana SQL isan-karazany hita ao amin'ny Internet dia hampiasaina ho ohatra.

fampidirana

Ny angon-drakitra mifandraika dia miasa amin'ny latabatra sy saha. Ao amin'ny angon-drakitra miasa, ny kilasy sy ny asa dia hampiasaina. Ny saha iray amin'ny latabatra misy fanalahidy N dia aseho ho toy ny fiasan'ny masontsivana N. Ho solon'ny fifandraisana eo amin'ny latabatra, dia hampiasaina ny fiasa izay mamerina ny zavatra ao amin'ny kilasy misy ny fifandraisana. Famoronana fiasa no hampiasaina fa tsy JOIN.

Alohan'ny hirosoana mivantana amin'ireo asa dia hamariparitra ny asan'ny lojika sehatra aho. Ho an'ny DDL dia hampiasa syntax PostgreSQL aho. Ho an'ny asa dia manana ny syntax azy manokana.

Tabilao sy saha

Zavatra Sku tsotra misy anarana sy sahan'ny vidiny:

fifandraisana

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

Miasa

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

Manambara roa izahay asa, izay maka Sku paramètre iray ho fampidirana ary mamerina karazana primitive.

Heverina fa ao amin'ny DBMS miasa ny zavatra tsirairay dia hanana kaody anatiny izay amboarina ho azy ary azo idirana raha ilaina.

Andao hametraka ny vidiny ho an'ny vokatra / fivarotana / mpamatsy. Mety hiova rehefa mandeha ny fotoana, ka ndao asiana saha-potoana eo amin'ny latabatra. Handalo ny filazana tabilao ho an'ny lahatahiry ao anaty angon-drakitra mifandraika aho mba hanafohezana ny kaody:

fifandraisana

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)
)

Miasa

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

fanondroana

Ho an'ny ohatra farany, hanangana fanondroana amin'ny fanalahidy rehetra sy ny daty isika mba hahafahantsika mahita haingana ny vidiny mandritra ny fotoana voafaritra.

fifandraisana

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

Miasa

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

asa

Andeha isika hanomboka amin'ny olana somary tsotra nalaina avy amin'ny mifanaraka lahatsoratra amin'ny Habr.

Voalohany, andao hanambara ny lojikan'ny sehatra (ho an'ny angon-drakitra mifandraika dia atao mivantana amin'ny lahatsoratra etsy ambony).

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);

Asa 1.1

Asehoy ny lisitry ny mpiasa mahazo karama lehibe kokoa noho ny an'ny mpanara-maso akaiky azy.

fifandraisana

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

Miasa

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

Asa 1.2

Tanisao ireo mpiasa mahazo ny karama ambony indrindra ao amin'ny departemanta misy azy

fifandraisana

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

Miasa

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));

Mitovy avokoa ny fampiharana roa. Ho an'ny tranga voalohany, amin'ny angon-drakitra relational dia azonao atao ny mampiasa CREATE VIEW, izay amin'ny fomba iray ihany no hanao kajy ny karama farany ambony indrindra ho an'ny departemanta manokana ao aminy. Amin'ity manaraka ity, mba hanazavana, dia hampiasa ny tranga voalohany aho, satria taratry ny vahaolana tsara kokoa izany.

Asa 1.3

Asehoy ny lisitry ny sampana ID, ny isan'ny mpiasa izay tsy mihoatra ny 3 olona.

fifandraisana

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

Miasa

countEmployees 'ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΡΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊΠΎΠ²' (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
SELECT Department d WHERE countEmployees(d) <= 3;

Asa 1.4

Asehoy ny lisitry ny mpiasa tsy manana mpitantana voatendry miasa ao amin'ny departemanta iray ihany.

fifandraisana

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

Miasa

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

Asa 1.5

Mitadiava lisitr'ireo ID departemanta misy ny totalin'ny karaman'ny mpiasa.

fifandraisana

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 )

Miasa

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();

Andeha isika hiroso amin'ny asa sarotra kokoa avy amin'ny hafa lahatsoratra. Misy famakafakana amin'ny antsipiriany momba ny fomba fampiharana io asa io amin'ny MS SQL.

Asa 2.1

Iza amin'ireo mpivarotra no namidy mihoatra ny 1997 ny vokatra No. 30 tamin'ny 1?

Lojikan'ny sehatra (toy ny teo aloha ao amin'ny RDBMS dia mandingana ny fanambarana izahay):

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);

fifandraisana

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

Miasa

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;

Asa 2.2

Ho an'ny mpividy tsirairay (anarana, anaram-bosotra), tadiavo ny entana roa (anarana) izay nandanian'ny mpividy vola be indrindra tamin'ny 1997.

Manitatra ny lojika sehatra izahay avy amin'ny ohatra teo aloha:

CLASS Customer 'ΠšΠ»ΠΈΠ΅Π½Ρ‚';
contactName 'ЀИО' = DATA STRING[100] (Customer);

customer = DATA Customer (Order);

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

fifandraisana

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

Miasa

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;

Ny mpandraharaha PARTITION dia miasa amin'ity fitsipika manaraka ity: mamintina ny teny voalaza ao aorian'ny SUM (eto 1), ao anatin'ireo vondrona voatondro (eto ny Mpanjifa sy ny Taona, fa mety ho fitenenana rehetra), manasokajy ao anatin'ny vondrona amin'ny fomba voalaza ao amin'ny ORDER ( eto novidina, ary raha mitovy, dia araka ny fehezan-dalΓ na anatiny).

Asa 2.3

Firy ny entana mila manafatra amin'ny mpamatsy mba hanatanterahana ny baiko ankehitriny.

Andao hanitatra indray ny lojika domain:

CLASS Supplier 'ΠŸΠΎΡΡ‚Π°Π²Ρ‰ΠΈΠΊ';
companyName = DATA STRING[100] (Supplier);

supplier = DATA Supplier (Product);

unitsInStock 'ΠžΡΡ‚Π°Ρ‚ΠΎΠΊ Π½Π° ΡΠΊΠ»Π°Π΄Π΅' = DATA NUMERIC[10,3] (Product);
reorderLevel 'Норма ΠΏΡ€ΠΎΠ΄Π°ΠΆΠΈ' = DATA NUMERIC[10,3] (Product);

fifandraisana

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

Miasa

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;

Olana amin'ny asterisk

Ary ny ohatra farany dia avy amiko manokana. Misy ny lojikan'ny tambajotra sosialy. Afaka ny ho mpinamana sy hifankatia ny olona. Avy amin'ny fomba fijery angon-drakitra functional dia ho toy izao:

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

Ilaina ny mitady olona mety ho mpinamana. Amin'ny fomba ofisialy kokoa, mila mitady ny olona rehetra A, B, C ianao ka i A dia naman'i B, ary i B dia naman'i C, A tia C, fa A tsy naman'i C.
Avy amin'ny fomba fijery angon-drakitra miasa, ny fangatahana dia ho toy izao:

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

Amporisihina ny mpamaky hamaha ity olana ity amin'ny SQL irery. Heverina fa vitsy kokoa ny namana noho ny olona tianao. Noho izany dia ao anaty latabatra misaraka izy ireo. Raha mahomby dia misy ihany koa ny asa misy kintana roa. Amin'izany, ny fisakaizana dia tsy symmetrika. Amin'ny angon-drakitra functional dia ho toy izao:

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: vahaolana amin'ny olana amin'ny asterisk voalohany sy faharoa avy amin'ny 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 

famaranana

Marihina fa ny syntax amin'ny fiteny nomena dia iray amin'ireo safidy amin'ny fampiharana ny hevitra nomena. Ny SQL dia noraisina ho fototra, ary ny tanjona dia ny hitovy amin'izany araka izay azo atao. Mazava ho azy fa mety tsy tian'ny sasany ny anaran'ny teny fototra, ny rejisitra teny, sns. Ny tena zava-dehibe eto dia ny foto-kevitra mihitsy. Raha tianao dia azonao atao ny manao syntax mitovy amin'ny C ++ sy Python.

Ny foto-kevitra momba ny angon-drakitra voalaza, araka ny hevitro, dia manana tombony manaraka:

  • hampitony. Ity dia tondro iray somary subjective izay tsy hita amin'ny tranga tsotra. Saingy raha mijery tranga sarotra kokoa ianao (ohatra, olana amin'ny asterisk), dia, araka ny hevitro, ny fanoratana fanontaniana toy izany dia mora kokoa.
  • Π˜Π½ΠΊΠ°ΠΏΡΡƒΠ»ΡΡ†ΠΈΡ. Amin'ny ohatra sasany dia nambarako ny fonction intermediate (ohatra, lafo, nividy sns.), izay nanorenana ny asa manaraka. Izany dia ahafahanao manova ny lojikan'ny asa sasany, raha ilaina, tsy manova ny lojikan'ireo izay miankina aminy. Ohatra, afaka manao varotra ianao lafo dia kajy avy amin'ny zavatra samy hafa tanteraka, fa ny sisa amin'ny lojika tsy hiova. Eny, azo ampiharina amin'ny RDBMS mampiasa CREATE VIEW izany. Fa raha toy izao no soratana ny lojika rehetra dia tsy ho azo vakina loatra.
  • Tsy misy elanelana semantika. Ny angon-drakitra toy izany dia miasa amin'ny fiasa sy kilasy (fa tsy latabatra sy saha). Tahaka ny amin'ny fandaharana klasika (raha heverinay fa ny fomba iray dia fiasa miaraka amin'ny mari-pamantarana voalohany amin'ny endriky ny kilasy misy azy). Noho izany dia tokony ho mora kokoa ny "manao namana" amin'ny fiteny fandaharana manerantany. Fanampin'izany, ity foto-kevitra ity dia mamela ny fampiharana sarotra kokoa. Ohatra, azonao atao ny mampiditra mpandraharaha toy ny:

    CONSTRAINT sold(Employee e, 1, 2019) > 100 IF name(e) = 'ΠŸΠ΅Ρ‚Ρ' MESSAGE  'Π§Ρ‚ΠΎ-Ρ‚ΠΎ ΠŸΠ΅Ρ‚я ΠΏΡ€ΠΎΠ΄Π°Π΅Ρ‚ ΡΠ»ΠΈΡˆΠΊΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΎΠ²Π°Ρ€Π° Π² 2019 Π³ΠΎΠ΄Ρƒ';

  • Fandovana sy polymorphisme. Ao amin'ny angon-drakitra miasa, azonao atao ny mampiditra lova marobe amin'ny alΓ lan'ny CLASS ClassP: Class1, Class2 manangana ary mampihatra polymorphisme marobe. Azo inoana fa hanoratra ny marina aho amin'ny lahatsoratra ho avy.

Na dia foto-kevitra fotsiny aza izany, dia efa manana fampiharana amin'ny Java isika izay mandika ny lojika miasa rehetra ho lojika mifandray. Fanampin'izay, ny lojikan'ny fanehoana sy ny zavatra maro hafa dia miraikitra tsara aminy, noho izany dia mahazo manontolo sehatra. Amin'ny ankapobeny, mampiasa ny RDBMS (PostgreSQL ihany izahay amin'izao fotoana izao) ho "milina virtoaly". Mipoitra indraindray ny olana amin'ity fandikan-teny ity satria tsy mahafantatra ny antontan'isa sasany fantatry ny FDBMS ny mpikaroka RDBMS. Amin'ny teoria, azo atao ny mametraka rafitra fitantanana angon-drakitra izay hampiasa rafitra iray ho fitahirizana, namboarina manokana ho an'ny lojika miasa.

Source: www.habr.com

Add a comment