SQL BAZE
Teoretski rad na kojem je zasnovan danas vodeći, relacijski tip baza podataka star je više od četiri desetljeća - Edgar F. Cood: A Relational Model of Data for Large Shared Data Banks (objavljen 1970. godine u časopisu Communications of the ACM). Na temelju navedenog rada u istaživačkom centru San Jose grupa IBM-ovih istraživača razvila je prvi sustav za upravljanje bazom podataka System R.
U Systemu R sve operacija nad podacima izvodile su se pomoću posebnog jezika nazvanog Structured English Query Language ili skraćeno SEQUEL. Budući da je korištenje tom skraćenicom SEQUEL u tom trenutku već bilo zaštićeno te ograničeno od strane britanske kompanije Hawker-Siddeley, prvobitni naziv jezika skraćen je na SQL (Structured Query Language). Premda je System R zasnovan na Coodovu radu, za sam jezik SQL zaslužna su druga dvojica IBM-ovih stručnjaka (Donald D. Chamberlin i Raymond F. Boyce).
Prvi komercijalni sustavi zasnovani na jeziku SQL pojavili su se tek 1979 godine. Te je godine IBM predstavio SQL/DS za računalo System/38. Iste godine drugi proizvođač softvera (Oracle Corporation – u to vrijeme Relation Software Inc) predstavio je tržištu svoj sustav za upravljanje relacijskim bazama podataka (Oracle Version 2).
Neke od ključnih prednosti relacijski orijentiranih baza podataka su:
- Zbog duge prisutnosti na tržištu dobro su poznate u teorijskom i u praktičnom smislu, što rezultira vrlo kvalitetnim i stabilnim softverskim rješenjima većeg broja proizvođača.
- Pristup i izvođenje operacija nad podacima su u standardiziranom i dobro poznatom jeziku upita SQL. Za navedeni jezik dostupna je ogromna podrška u različitim oblicima (knjige, priručnici, tečajevi i ostalo).
- Primjena relacijski orijentiranih baza podataka dobro je poznata i s financijske strane pa je jednostavnije planirati troškove uvođenja novih sustava ili nadogradnje postojećih.
- Osnovni pojmovi u relacijskom modelu (poput tablica, stupaca i ostalo) relativno su jednostavni za razumijevanje.
Kao glavne negativne karakteristike može se istaknuti sljedeće:
- Relacijske baze podataka (pogotovo nešto starije verzije) ne podržavaju izravno neke od oblika podataka koji se sve češće pojavljuju u modernim poslovnim i/ili multimedijalno orijentiranim IT sustavima.
- Kod grupiranja osnovnih tipova podataka u složenije strukture podataka relacijski model podataka često nije optimalan u pogledu performansi sustava.
- Standardni SQL jezik upita također ne predstavlja optimalan izbor za pristup nestandardnim oblicima podataka.
- Za pristup podacima potrebno je razumjeti strukturu i organizaciju baze podataka.
- Interni mehanizmi zaključavanja resursa nisu pogodni za određene složene tipove podataka.
NoSQL BAZE
Nabrojene nedostatke relacijskih baza podataka, nerelacijske ili NoSQL baze podataka pokušavaju riješiti na različite načine. Zbog toga se ne može govoriti o jedinstvenom NoSQL modelu baze podataka, nego o većem broju različitih modela podržanih od strane manjeg ili većeg broja proizvođača. Neke od najvažnijih grupa NoSQL baza podataka su (nazive navodimo u originalu):
- Document Databases
- Graph Databases
- Columnar Databases
- In-Memory Data Grids.
Document Databases
Jedan od najpoznatijih oblika NoSQL baza podataka su takozvane baze dokumenata. Umjesto korištenja tablica za spremanje jednostavnih vrsta podataka u stupcima, u ovom modelu osnovnu „jedinicu podataka“ predstavlja dokument zajedno s različitim dodatnim metapodacima o samom dokumentu. U slučaju da u bazi podataka treba čuvati samo jednu i to točno određenu vrstu dokumenata, takav slučaj može se relativno jednostavno simulirati i relacijskim bazama podataka upotrebom dodatnih stupaca s najvažnijim metapodacima o dokumentu. Problemi kod relacijskog modela nastaju kad u istoj bazi treba čuvati veliku količinu međusobno različitih dokumenata. U takvom slučaju baze dokumenata predstavljaju prikladniji način za spremanje podataka. Uz prirodnu podršku za spremanje različitih vrsta dokumenata i njihovih metadapodataka, one istovremeno dozvoljavaju uspostavljanje odgovarajućih veza između dokumenata.
Kao jedan od najpoznatijih primjera baze dokumenata spomenut ćemo MongoDB. Prva verzija razvijena je 2007 godine (dakle skoro 30 godina nakon prvih verzija relacijskih baza podataka), od strane MongoDB Inc (u trenutku nastanka 10gen). MongoDB se za spremanje dokumenata koristi podacima pripremljenim u JSON (JavaScript Object Notation) formatu uz uključenu podršku za dinamičke sheme podataka. To znači da na početku rada s bazom podataka nije potrebno znati sve detalje o tome kakvi će se dokumenti spremati u bazu.
Slijedi primjer upisa istih podataka u relacijsku bazu podataka (Microsoft SQL Server) te bazu dokumenata (MongoDB). Uz pretpostavku da u oba slučaja u bazi podataka ne postoji već pripremljena struktura za spremanje podataka, u slučaju relacijske baze podataka potrebno je prvo pokrenuti dodatne DDL (Data Definition Language) naredbe za njezinu pripremu, a tek onda slijede DML (Data Manipulation Language) naredbe za dodavanje podataka u tablice. U slučaju baze dokumenata MongoDB, samom naredbom za spremanje podataka automatski se pripremaju sve potrebne strukture.
Microsoft SQL Server
CREATE TABLE [dbo].[Orders](
[OrderID] [int] IDENTITY(1,1) NOT NULL,
[CustomerID] [nchar](5) NULL,
[EmployeeID] [int] NULL,
[OrderDate] [datetime] NULL,
[RequiredDate] [datetime] NULL,
[ShippedDate] [datetime] NULL,
[ShipVia] [int] NULL,
[Freight] [money] NULL CONSTRAINT [DF_Orders_Freight] DEFAULT ((0)),
[ShipName] [nvarchar](40) NULL,
[ShipAddress] [nvarchar](60) NULL,
[ShipCity] [nvarchar](15) NULL,
[ShipRegion] [nvarchar](15) NULL,
[ShipPostalCode] [nvarchar](10) NULL,
[ShipCountry] [nvarchar](15) NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[OrderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Order Details](
[OrderID] [int] NOT NULL,
[ProductID] [int] NOT NULL,
[UnitPrice] [money] NOT NULL CONSTRAINT [DF_Order_Details_UnitPrice] DEFAULT ((0)),
[Quantity] [smallint] NOT NULL CONSTRAINT [DF_Order_Details_Quantity] DEFAULT ((1)),
[Discount] [real] NOT NULL CONSTRAINT [DF_Order_Details_Discount] DEFAULT ((0)),
CONSTRAINT [PK_Order_Details] PRIMARY KEY CLUSTERED
(
[OrderID] ASC,
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET IDENTITY_INSERT [dbo].[Orders] ON
INSERT [dbo].[Orders] ([OrderID], [CustomerID], [EmployeeID], [OrderDate], [RequiredDate], [ShippedDate], [ShipVia], [Freight], [ShipName], [ShipAddress], [ShipCity], [ShipRegion], [ShipPostalCode], [ShipCountry]) VALUES (10248, N'VINET', 5, CAST(N'1996-07-04 00:00:00.000' AS DateTime), CAST(N'1996-08-01 00:00:00.000' AS DateTime), CAST(N'1996-07-16 00:00:00.000' AS DateTime), 3, 32.3800, N'Vins et alcools Chevalier', N'59 rue de l''Abbaye', N'Reims', NULL, N'51100', N'France')
GO
SET IDENTITY_INSERT [dbo].[Orders] OFF
GO
INSERT [dbo].[Order Details] ([OrderID], [ProductID], [UnitPrice], [Quantity], [Discount]) VALUES (10248, 11, 14.0000, 12, 0)
INSERT [dbo].[Order Details] ([OrderID], [ProductID], [UnitPrice], [Quantity], [Discount]) VALUES (10248, 42, 9.8000, 10, 0)
INSERT [dbo].[Order Details] ([OrderID], [ProductID], [UnitPrice], [Quantity], [Discount]) VALUES (10248, 72, 34.8000, 5, 0)
GO
MongoDB
db.orders.insert(
{
"order" : {
"orderID" : 10248,
"customerID" : "VINET",
"employeeID" : 5,
"orderDate" : ISODate("1996-07-04T00:00:00Z"),
"requiredDate" : ISODate("1996-08-01T00:00:00Z"),
"shippedDate" : ISODate("1996-07-16T00:00:00Z"),
"shipVia" : 3,
"freight" : 32.3800,
"shipName" : "Vins et alcools Chevalier",
"shipAddress" : "59 rue de l'Abbaye",
"shipCity" : "Reims",
"shipRegion" : null,
"ShipPostalCode" : "51100",
"ShipCountry" : "France"
},
"orderDetails" : [
{
"orderID" : 10248,
"productID" : 11,
"unitPrice" : 14.0000,
"quantity" : 12,
"discount" : 0
},
{
"orderID" : 10248,
"productID" : 42,
"unitPrice" : 9.8000,
"quantity" : 10,
"discount" : 0
},
{
"orderID" : 10248,
"productID" : 72,
"unitPrice" : 34.8000,
"quantity" : 5,
"discount" : 0
}
]
}
)
U stvarnom svijetu potpuni primjer za relacijski model u pravilu je još složeniji, jer se obično na tablicama definiraju dodatne stvari poput podrazumijevanih vrijednosti, ograničenja i slično. Na primjer, nešto poput:
ALTER TABLE [dbo].[Order Details] WITH NOCHECK ADD CONSTRAINT [FK_Order_Details_Orders] FOREIGN KEY([OrderID])
REFERENCES [dbo].[Orders] ([OrderID])
GO
ALTER TABLE [dbo].[Order Details] CHECK CONSTRAINT [FK_Order_Details_Orders]
GO
ALTER TABLE [dbo].[Order Details] WITH NOCHECK ADD CONSTRAINT [CK_Discount] CHECK (([Discount]>=(0) AND [Discount]<=(1)))
GO
ALTER TABLE [dbo].[Order Details] CHECK CONSTRAINT [CK_Discount]
GO
ALTER TABLE [dbo].[Order Details] WITH NOCHECK ADD CONSTRAINT [CK_Quantity] CHECK (([Quantity]>(0)))
GO
ALTER TABLE [dbo].[Order Details] CHECK CONSTRAINT [CK_Quantity]
GO
Iako su takve mogućnosti poželjne radi očuvanja integriteta podataka, istovremeno predstavljaju otežavajuću okolnost za sustav u pogledu performansi na ogromnoj količini podataka.
U sljedećem tekstu bit će objašnjena razlika između relacijskih baza podataka i još nekoliko drugih popularnih tipova NoSQL baza podataka.