Is iad na DBMSanna coibhneasta, a úsáideann an teanga SQL, is mó a bhí i ndomhan na mbunachair shonraí le fada an lá. An oiread sin go dtugtar NoSQL ar na leaganacha atá ag teacht chun cinn. D'éirigh leo áit áirithe a bhaint amach dóibh féin sa mhargadh seo, ach níl DBMSanna coibhneasta ag dul chun bás, agus leanfar de bheith á n-úsáid go gníomhach chun a gcríocha.
San Airteagal seo ba mhaith liom cur síos a dhéanamh ar choincheap bunachar sonraí feidhme. Ar mhaithe le tuiscint níos fearr, déanfaidh mé é seo trí é a chur i gcomparáid leis an tsamhail choibhneasta clasaiceach. Úsáidfear fadhbanna ó thástálacha SQL éagsúla a fhaightear ar an Idirlíon mar shamplaí.
Réamhrá
Feidhmíonn bunachair shonraí choibhneasta ar tháblaí agus ar réimsí. I mbunachar sonraí feidhme, bainfear úsáid as ranganna agus feidhmeanna ina ionad sin, faoi seach. Léireofar réimse i dtábla le N eochracha mar fheidhm de pharaiméadair N. In ionad gaolta idir táblaí, úsáidfear feidhmeanna a fhilleann rudaí den aicme lena ndéantar an nasc. Bainfear úsáid as comhdhéanamh feidhme in ionad JOIN.
Sula mbogfaidh mé go díreach chuig na tascanna, déanfaidh mé cur síos ar an tasc a bhaineann le loighic fearainn. Le haghaidh DDL úsáidfidh mé comhréir PostgreSQL. Le haghaidh feidhme tá a chomhréir féin aige.
Táblaí agus réimsí
Réad Sku simplí le réimsí ainm agus praghsanna:
Gaolmhar
CREATE TABLE Sku
(
id bigint NOT NULL,
name character varying(100),
price numeric(10,5),
CONSTRAINT id_pkey PRIMARY KEY (id)
)
Feidhmiúil
CLASS Sku;
name = DATA STRING[100] (Sku);
price = DATA NUMERIC[10,5] (Sku);
Fógraímid beirt feidhmeanna, a thógann Sku paraiméadar amháin mar ionchur agus cineál primitive a thabhairt ar ais.
Glactar leis go mbeidh cód inmheánach éigin ag gach réad i DBMS feidhme a ghintear go huathoibríoch agus gur féidir rochtain a fháil air más gá.
Socróimid an praghas don táirge/siopa/soláthraí. Féadfaidh sé athrú le himeacht ama, mar sin cuirimis réimse ama leis an tábla. Ní dhéanfaidh mé táblaí le haghaidh eolairí a dhearbhú i mbunachar sonraí coibhneasta chun an cód a ghiorrú:
Gaolmhar
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)
)
Feidhmiúil
CLASS Sku;
CLASS Store;
CLASS Supplier;
dateTime = DATA DATETIME (Sku, Store, Supplier);
price = DATA NUMERIC[10,5] (Sku, Store, Supplier);
Innéacsanna
Mar shampla deireanach, tógfaimid innéacs ar na heochracha go léir agus an dáta ionas gur féidir linn an praghas a fháil go tapa ar feadh tréimhse ama ar leith.
Gaolmhar
CREATE INDEX prices_date
ON prices
(skuId, storeId, supplierId, dateTime)
Feidhmiúil
INDEX Sku sk, Store st, Supplier sp, dateTime(sk, st, sp);
tascanna
Let tús le fadhbanna réasúnta simplí a tógadh as an comhfhreagrach
Ar dtús, déanaimis loighic an fhearainn a dhearbhú (don bhunachar sonraí coibhneasta déantar é seo go díreach san alt thuas).
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);
Tasc 1.1
Taispeáin liosta fostaithe a fhaigheann tuarastal níos mó ná tuarastal a maoirseora láithreach.
Gaolmhar
select a.*
from employee a, employee b
where b.id = a.chief_id
and a.salary > b.salary
Feidhmiúil
SELECT name(Employee a) WHERE salary(a) > salary(chief(a));
Tasc 1.2
Déan liosta de na fostaithe a fhaigheann an t-uastuarastal ina Roinn
Gaolmhar
select a.*
from employee a
where a.salary = ( select max(salary) from employee b
where b.department_id = a.department_id )
Feidhmiúil
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));
Is ionann an dá fheidhmiúchán. Don chéad chás, i mbunachar sonraí coibhneasta is féidir leat úsáid a bhaint as CREATE VIEW, a bheidh ar an mbealach céanna a ríomh ar dtús leis an tuarastal uasta do roinn ar leith ann. Sa mhéid seo a leanas, ar mhaithe le soiléireacht, úsáidfidh mé an chéad chás, ós rud é go léiríonn sé an réiteach níos fearr.
Tasc 1.3
Taispeáin liosta de na IDs roinn, líon na bhfostaithe i nach mó ná 3 daoine.
Gaolmhar
select department_id
from employee
group by department_id
having count(*) <= 3
Feidhmiúil
countEmployees 'Количество сотрудников' (Department d) =
GROUP SUM 1 IF department(Employee e) = d;
SELECT Department d WHERE countEmployees(d) <= 3;
Tasc 1.4
Taispeáin liosta fostaithe nach bhfuil bainisteoir ainmnithe ag obair sa roinn chéanna.
Gaolmhar
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
Feidhmiúil
SELECT name(Employee a) WHERE NOT (department(chief(a)) = department(a));
Tasc 1.5
Faigh liosta d’aitheantais na roinne le huastuarastal iomlán an fhostaí.
Gaolmhar
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 )
Feidhmiúil
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();
A ligean ar bogadh ar aghaidh go dtí tascanna níos casta ó eile
Tasc 2.1
Cé na díoltóirí a dhíol níos mó ná 1997 aonad de tháirge Uimh. 30 i 1?
Loighic fearainn (mar a rinneadh roimhe seo ar RDBMS ní dhéanaimid an dearbhú):
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);
Gaolmhar
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
Feidhmiúil
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;
Tasc 2.2
I gcás gach ceannaitheoir (ainm, sloinne), faigh an dá earra (ainm) ar ar chaith an ceannaitheoir an t-airgead is mó i 1997.
Leathnaímid loighic an fhearainn ón sampla roimhe seo:
CLASS Customer 'Клиент';
contactName 'ФИО' = DATA STRING[100] (Customer);
customer = DATA Customer (Order);
unitPrice = DATA NUMERIC[14,2] (Detail);
discount = DATA NUMERIC[6,2] (Detail);
Gaolmhar
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
Feidhmiúil
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;
Oibríonn an t-oibreoir PARTITION ar an bprionsabal seo a leanas: suimíonn sé an slonn a shonraítear tar éis SUM (anseo 1), laistigh de na grúpaí sonraithe (anseo Custaiméir agus Bliain, ach d'fhéadfadh a bheith ar aon abairt), sórtáil laistigh de na grúpaí de réir na habairtí a shonraítear san ORDÚ ( anseo ceannaithe, agus más comhionann, ansin de réir an chóid táirge inmheánaigh).
Tasc 2.3
Cé mhéad earraí is gá a ordú ó sholáthróirí chun orduithe reatha a chomhlíonadh.
Déanaimis loighic an fhearainn a leathnú arís:
CLASS Supplier 'Поставщик';
companyName = DATA STRING[100] (Supplier);
supplier = DATA Supplier (Product);
unitsInStock 'Остаток на складе' = DATA NUMERIC[10,3] (Product);
reorderLevel 'Норма продажи' = DATA NUMERIC[10,3] (Product);
Gaolmhar
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
Feidhmiúil
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;
Fadhb le réiltín
Agus tá an sampla deireanach uaimse go pearsanta. Tá an loighic líonra sóisialta. Is féidir le daoine a bheith ina gcairde lena chéile agus cosúil lena chéile. Ó thaobh bunachar sonraí feidhme de bheadh cuma mar seo air:
CLASS Person;
likes = DATA BOOLEAN (Person, Person);
friends = DATA BOOLEAN (Person, Person);
Is gá iarrthóirí féideartha a aimsiú le haghaidh cairdeas. Ar bhonn níos foirmeálta, ní mór duit na daoine go léir A, B, C a aimsiú ionas go bhfuil A cairde le B, agus B cairde le C, is maith le A C, ach nach bhfuil A cairde le C.
Ó thaobh bunachar sonraí feidhme de, is mar seo a bheadh an chuma ar an gceist:
SELECT Person a, Person b, Person c WHERE
likes(a, c) AND NOT friends(a, c) AND
friends(a, b) AND friends(b, c);
Spreagtar an léitheoir an fhadhb seo a réiteach in SQL leis féin. Glactar leis go bhfuil i bhfad níos lú cairde ná daoine a thaitníonn leat. Dá bhrí sin tá siad i dtáblaí ar leith. Má éiríonn leis, tá tasc le dhá réalta ann freisin. I sé, nach bhfuil cairdeas siméadrach. Ar bhunachar sonraí feidhme bheadh cuma mar seo air:
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: réiteach ar an bhfadhb leis an gcéad agus an dara réiltín ó
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
Conclúid
Ba chóir a thabhairt faoi deara nach bhfuil sa chomhréir teanga ach ceann amháin de na roghanna chun an coincheap tugtha a chur i bhfeidhm. Glacadh SQL mar bhunús, agus ba é an sprioc go mbeadh sé chomh cosúil agus ab fhéidir leis. Ar ndóigh, b’fhéidir nach dtaitníonn cuid acu le hainmneacha eochairfhocail, cláir focal, etc. Is é an rud is mó anseo an coincheap féin. Más mian leat, is féidir leat comhréir comhchosúil C ++ agus Python a dhéanamh.
Tá na buntáistí seo a leanas ag baint le coincheap an bhunachair shonraí a gcuirtear síos air, i mo thuairim:
- Simplíocht. Is táscaire sách suibiachtúil é seo nach bhfuil soiléir i gcásanna simplí. Ach má fhéachann tú ar chásanna níos casta (mar shampla, fadhbanna le réiltíní), ansin, i mo thuairim, tá sé i bhfad níos éasca ceisteanna den sórt sin a scríobh.
- Инкапсуляция. I roinnt samplaí dhearbhaigh mé feidhmeanna idirmheánacha (mar shampla, a dhíoltar, Cheannaigh etc.), ónar tógadh feidhmeanna ina dhiaidh sin. Ligeann sé seo duit loighic feidhmeanna áirithe a athrú, más gá, gan loighic na ndaoine atá ag brath orthu a athrú. Mar shampla, is féidir leat díolacháin a dhéanamh a dhíoltar a ríomh ó rudaí go hiomlán difriúil, cé nach mbeidh an chuid eile den loighic a athrú. Is féidir, is féidir é seo a chur i bhfeidhm i RDBMS ag baint úsáide as CREATE VIEW. Ach má scríobhtar an loighic ar fad ar an mbealach seo, ní bheidh cuma an-inléite air.
- Gan aon bhearna shéimeantach. Feidhmíonn bunachar sonraí den sórt sin ar fheidhmeanna agus ar aicmí (in ionad táblaí agus réimsí). Díreach mar atá i ríomhchlárú clasaiceach (má ghlacaimid leis gur feidhm é modh leis an gcéad pharaiméadar i bhfoirm an aicme lena mbaineann sé). Dá réir sin, ba cheart go mbeadh sé i bhfad níos éasca “cairde a dhéanamh” le teangacha ríomhchlárúcháin uilíoch. Ina theannta sin, ceadaíonn an coincheap seo feidhmiúlacht i bhfad níos casta a chur i bhfeidhm. Mar shampla, is féidir leat oibreoirí a leabú mar:
CONSTRAINT sold(Employee e, 1, 2019) > 100 IF name(e) = 'Петя' MESSAGE 'Что-то Петя продает слишком много одного товара в 2019 году';
- Oidhreacht agus polymorphism. I mbunachar sonraí feidhme, is féidir leat oidhreacht iolrach a thabhairt isteach tríd an AICME AicmeP: Tógann Class1, Class2 il-ilmhoirfeas agus cuireann sé i bhfeidhm é. Is dócha go scríobhfaidh mé go díreach in ailt amach anseo.
Cé nach bhfuil anseo ach coincheap, tá roinnt cur chun feidhme againn cheana féin i Java a aistríonn an loighic fheidhmiúil go léir go loighic choibhneasta. Ina theannta sin, tá loighic na n-uiríll agus go leor rudaí eile ceangailte go hálainn leis, agus a bhuíochas sin a fháil againn ar fad
Foinse: will.com