Tha saoghal nan stòran-dàta air a bhith fo smachd o chionn fhada le DBMSan dàimheach, a bhios a’ cleachdadh cànan SQL. Na h-uimhir gus an canar NoSQL ri caochlaidhean a tha a’ tighinn am bàrr. Chaidh aca air àite sònraichte a shnaigheadh a-mach dhaibh fhèin sa mhargaidh seo, ach chan eil DBMSan dàimheach gu bhith a’ bàsachadh, agus tha iad fhathast gan cleachdadh gu gnìomhach airson an adhbharan.
San artaigil seo tha mi airson cunntas a thoirt air bun-bheachd stòr-dàta gnìomh. Airson tuigse nas fheàrr, nì mi seo le bhith ga choimeas ris a’ mhodail dhàimheach clasaigeach. Thèid duilgheadasan bho dhiofar dheuchainnean SQL a lorgar air an eadar-lìn a chleachdadh mar eisimpleirean.
Ro-ràdh
Bidh stòran-dàta càirdeach ag obrachadh air clàran agus raointean. Ann an stòr-dàta gnìomh, thèid clasaichean agus gnìomhan a chleachdadh nan àite, fa leth. Bidh raon ann an clàr le iuchraichean N air a riochdachadh mar dhleastanas air paramadairean N. An àite dàimhean eadar bùird, thèid gnìomhan a chleachdadh a thilleas nithean den chlas ris a bheil an ceangal air a dhèanamh. Thèid sgrìobhadh gnìomh a chleachdadh an àite JOIN.
Mus gluais thu gu dìreach gu na gnìomhan, bheir mi cunntas air gnìomh loidsig fearainn. Airson DDL cleachdaidh mi co-chòrdadh PostgreSQL. Airson gnìomh tha a cho-chòrdadh fhèin aige.
Clàran agus raointean
Rud Sku sìmplidh le raointean ainm is prìsean:
Dàimheach
CREATE TABLE Sku
(
id bigint NOT NULL,
name character varying(100),
price numeric(10,5),
CONSTRAINT id_pkey PRIMARY KEY (id)
)
Gnìomh
CLASS Sku;
name = DATA STRING[100] (Sku);
price = DATA NUMERIC[10,5] (Sku);
Bidh sinn ag ainmeachadh dhà gnìomhan, a bheir aon paramadair Sku mar chur-a-steach agus a 'tilleadh seòrsa prìomhadail.
Thathas a’ gabhail ris gum bi còd a-staigh aig gach nì ann an DBMS gnìomh a thèid a chruthachadh gu fèin-ghluasadach agus a gheibhear thuige ma tha sin riatanach.
Nach suidhich sinn a’ phrìs airson an toradh/stòr/solaraiche. Dh’ fhaodadh e atharrachadh thar ùine, mar sin leig dhuinn raon ùine a chur ris a’ chlàr. Bidh mi a’ sgioblachadh clàran airson clàran ann an stòr-dàta dàimheach gus an còd a ghiorrachadh:
Dàimheach
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)
)
Gnìomh
CLASS Sku;
CLASS Store;
CLASS Supplier;
dateTime = DATA DATETIME (Sku, Store, Supplier);
price = DATA NUMERIC[10,5] (Sku, Store, Supplier);
Clàran-innse
Airson an eisimpleir mu dheireadh, togaidh sinn clàr-amais air a h-uile iuchair agus an ceann-latha gus an lorg sinn gu luath am prìs airson ùine shònraichte.
Dàimheach
CREATE INDEX prices_date
ON prices
(skuId, storeId, supplierId, dateTime)
Gnìomh
INDEX Sku sk, Store st, Supplier sp, dateTime(sk, st, sp);
gnìomhan
Feuch an tòisich sinn le duilgheadasan an ìre mhath sìmplidh air an toirt bhon cho-fhreagarrach
An toiseach, leig dhuinn loidsig an àrainn ainmeachadh (airson an stòr-dàta dàimheach tha seo air a dhèanamh gu dìreach san artaigil gu h-àrd).
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);
Tasg 1.1
Seall liosta de luchd-obrach a gheibh tuarastal nas àirde na an neach-stiùiridh aca.
Dàimheach
select a.*
from employee a, employee b
where b.id = a.chief_id
and a.salary > b.salary
Gnìomh
SELECT name(Employee a) WHERE salary(a) > salary(chief(a));
Tasg 1.2
Dèan liosta den luchd-obrach a gheibh an tuarastal as àirde san roinn aca
Dàimheach
select a.*
from employee a
where a.salary = ( select max(salary) from employee b
where b.department_id = a.department_id )
Gnìomh
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));
Tha an dà bhuileachadh co-ionann. Airson a 'chiad chùis, ann an stòr-dàta dàimh faodaidh tu CREATE VIEW a chleachdadh, a bhios san aon dòigh a' obrachadh a-mach an tuarastal as àirde airson roinn shònraichte ann. Anns na leanas, airson soilleireachd, cleachdaidh mi a 'chiad chùis, oir tha e nas fheàrr a' nochdadh an fhuasglaidh.
Tasg 1.3
Taisbeanaidh liosta de IDan roinne, an àireamh de luchd-obrach anns nach eil barrachd air 3 neach.
Dàimheach
select department_id
from employee
group by department_id
having count(*) <= 3
Gnìomh
countEmployees 'Количество сотрудников' (Department d) =
GROUP SUM 1 IF department(Employee e) = d;
SELECT Department d WHERE countEmployees(d) <= 3;
Tasg 1.4
Seall liosta de luchd-obrach aig nach eil manaidsear ainmichte ag obair san aon roinn.
Dàimheach
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
Gnìomh
SELECT name(Employee a) WHERE NOT (department(chief(a)) = department(a));
Tasg 1.5
Lorg liosta de IDan roinnean leis an tuarastal iomlan luchd-obrach as àirde.
Dàimheach
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 )
Gnìomh
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();
Gluaisidh sinn air adhart gu gnìomhan nas iom-fhillte bho neach eile
Tasg 2.1
Dè an luchd-reic a reic còrr is 1997 aonad de bhathar Àir. 30 ann an 1?
Loidsig fearainn (mar a bha roimhe air RDBMS bidh sinn a’ leum air an dearbhadh):
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);
Dàimheach
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
Gnìomh
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;
Tasg 2.2
Airson gach ceannaiche (ainm, sloinneadh), lorg an dà bhathar (ainm) air an do chuir an ceannaiche seachad an airgead as motha ann an 1997.
Bidh sinn a’ leudachadh loidsig na h-àrainn bhon eisimpleir roimhe:
CLASS Customer 'Клиент';
contactName 'ФИО' = DATA STRING[100] (Customer);
customer = DATA Customer (Order);
unitPrice = DATA NUMERIC[14,2] (Detail);
discount = DATA NUMERIC[6,2] (Detail);
Dàimheach
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
Gnìomh
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;
Bidh an gnìomhaiche PÀIRT ag obair air a’ phrionnsapal a leanas: bidh e a’ toirt cunntas air an abairt a chaidh a shònrachadh às deidh SUM (an seo 1), taobh a-staigh nam buidhnean ainmichte (an seo Luchd-ceannach agus Bliadhna, ach dh’ fhaodadh gur e abairt sam bith a th ’ann), a’ rèiteachadh taobh a-staigh nam buidhnean a rèir na h-abairtean a tha air an sònrachadh san ORDER ( an seo air a cheannach, agus ma tha e co-ionann, an uairsin a rèir a’ chòd toraidh a-staigh).
Tasg 2.3
Cia mheud bathar a dh’ fheumar òrdachadh bho sholaraichean gus òrdughan gnàthach a choileanadh.
Leudaichidh sinn loidsig na h-àrainn a-rithist:
CLASS Supplier 'Поставщик';
companyName = DATA STRING[100] (Supplier);
supplier = DATA Supplier (Product);
unitsInStock 'Остаток на складе' = DATA NUMERIC[10,3] (Product);
reorderLevel 'Норма продажи' = DATA NUMERIC[10,3] (Product);
Dàimheach
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
Gnìomh
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;
Trioblaid le rionnag
Agus tha an eisimpleir mu dheireadh bhuam gu pearsanta. Tha loidsig lìonra sòisealta ann. Faodaidh daoine a bhith nan caraidean dha chèile agus coltach ri chèile. Bho shealladh stòr-dàta gnìomh bhiodh e a’ coimhead mar seo:
CLASS Person;
likes = DATA BOOLEAN (Person, Person);
friends = DATA BOOLEAN (Person, Person);
Tha e riatanach tagraichean a lorg airson càirdeas. Nas foirmeile, feumaidh tu a h-uile duine A, B, C a lorg gus am bi A na charaidean le B, agus B na charaidean le C, is toil le A C, ach chan eil A na charaidean le C.
Bho shealladh stòr-dàta gnìomh, bhiodh a’ cheist a’ coimhead mar seo:
SELECT Person a, Person b, Person c WHERE
likes(a, c) AND NOT friends(a, c) AND
friends(a, b) AND friends(b, c);
Tha an leughadair air a bhrosnachadh gus an duilgheadas seo fhuasgladh ann an SQL leis fhèin. Thathas a’ gabhail ris gu bheil tòrr nas lugha de charaidean ann na tha daoine a’ còrdadh riut. Mar sin tha iad ann an clàran fa leth. Ma tha e soirbheachail, tha gnìomh ann cuideachd le dà rionnag. Ann an sin, chan eil càirdeas co-chothromach. Air stòr-dàta gnìomh bhiodh e a’ coimhead mar seo:
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: fuasgladh air an duilgheadas leis a’ chiad agus an dàrna rionnag bho
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
co-dhùnadh
Bu chòir a thoirt fa-near gur e an co-chòrdadh cànain a chaidh a thoirt seachad dìreach aon de na roghainnean airson a’ bhun-bheachd a chaidh a thoirt seachad a bhuileachadh. Chaidh SQL a ghabhail mar bhunait, agus b 'e an t-amas gum biodh e cho coltach' sa ghabhas ris. Gu dearbh, is dòcha nach toil le cuid ainmean prìomh fhaclan, clàran fhaclan, msaa. Is e am prìomh rud an seo am bun-bheachd fhèin. Ma thogras tu, faodaidh tu an dà chuid C ++ agus Python co-chòrdadh coltach ris a dhèanamh.
Tha na buannachdan a leanas aig bun-bheachd an stòr-dàta a chaidh a mhìneachadh, nam bheachd-sa:
- faochadh. Is e comharradh caran cuspaireil a tha seo nach eil follaiseach ann an cùisean sìmplidh. Ach ma choimheadas tu air cùisean nas iom-fhillte (mar eisimpleir, duilgheadasan le reultan), an uairsin, nam bheachd-sa, tha e tòrr nas fhasa a leithid de cheistean a sgrìobhadh.
- Инкапсуляция. Ann an cuid de dh’ eisimpleirean dh’ainmich mi gnìomhan eadar-mheadhanach (mar eisimpleir, reic, cheannaich msaa), às an deach gnìomhan a thogail às deidh sin. Leigidh seo leat loidsig gnìomhan sònraichte atharrachadh, ma tha sin riatanach, gun a bhith ag atharrachadh loidsig an fheadhainn a tha an urra riutha. Mar eisimpleir, faodaidh tu reic a dhèanamh reic air an tomhas bho nithean gu tur eadar-dhealaichte, fhad ‘s nach atharraich an còrr den loidsig. Faodaidh, faodar seo a chuir an gnìomh ann an RDBMS a’ cleachdadh CREATE VIEW. Ach ma thèid an loidsig gu lèir a sgrìobhadh san dòigh seo, cha bhith e a’ coimhead gu math furasta a leughadh.
- Gun bheàrn semantach. Bidh stòr-dàta mar seo ag obair air gnìomhan agus clasaichean (an àite clàran agus raointean). Dìreach mar ann am prògramadh clasaigeach (ma tha sinn a 'gabhail ris gur e gnìomh a th' ann an dòigh leis a 'chiad paramadair ann an cruth a' chlas dha bheil e). Mar sin, bu chòir gum biodh e fada nas fhasa “caraidean a dhèanamh” le cànanan prògramaidh uile-choitcheann. A bharrachd air an sin, tha am bun-bheachd seo a’ ceadachadh gnìomhachd mòran nas iom-fhillte a chuir an gnìomh. Mar eisimpleir, faodaidh tu gnìomhaichean leithid:
CONSTRAINT sold(Employee e, 1, 2019) > 100 IF name(e) = 'Петя' MESSAGE 'Что-то Петя продает слишком много одного товара в 2019 году';
- Oighreachd agus polymorphism. Ann an stòr-dàta gnìomh, faodaidh tu iomadh oighreachd a thoirt a-steach tro CLASS ClassP: Clas 1, Clas 2 a’ togail agus a’ cur an gnìomh ioma polymorphism. Is dòcha gun sgrìobh mi cho dìreach ann an artaigilean san àm ri teachd.
Eadhon ged nach e dìreach bun-bheachd a tha seo, tha beagan buileachaidh againn mu thràth ann an Java a tha ag eadar-theangachadh a h-uile loidsig gnìomh gu loidsig dàimh. A bharrachd air an sin, tha loidsig riochdachaidhean agus tòrr rudan eile ceangailte gu breagha ris, leis am faigh sinn slàn
Source: www.habr.com