Baze de Date Pentru Un Operator de Telecomunicatii

Proiect de diplomă

Baze de date pentru un operator de telecomunicații

Introducere

Fiecare din marile companii de telecomunicații din România, oferă servicii în funcție de scopul clienților: prepay, abonamente de voce, abonamente de date și voce. Așadar o companie va avea nevoie de o bază de date pentru controlul datelor atribuite clienților săi.

Este important ca adaugarea unui client în baza de date a companiei să se facă rapid, iar în prelucrarea datelor să nu apară erori, ca de exemplu introducerea unui număr de mai multe ori.

Acest proiect prezintă atât modul în care se realizează o bază de date în domeniul telecomunicațiilor cât și importanța fiecărei acțiuni realizate. Dintr-o bază de date se pot extrage doar informațiile necesare, nu un întreg tabel din care ar fi dificil sublinierea celor necesare.

În vederea creării, modificării și ștergerii unor baze de date sau a înregistrărilor din tabelele ce alcătuiesc baze de date trebuie implementați utilizatorii care au drepturi mai mult sau mai puțin limitate în activitatea lor. După ce aceștia sunt creați, împreună cu ei vor fi create și anumite înregistrări în baza de date și voi evidenția utilitatea acestor baze de date.

Se are în vedere prezentarea unor noțini introductive în baze de date, definiția unei baze de date, relație, entitate, atribut și tabele. Apoi voi prezenta scenariul de plecare pentru construirea bazei de date modul de creare al utilizatorilor, ce drepturi ar putea fi asociate acestora asupra bazelor de date, pașii pe care un operator îi face pentru a popula tabelele cu date, creerea de relații între tabele și a vederilor.

De asemenea se va proiecta un site in limbajele HTML, CSS, PHP si MySQL care va reprezenta interfata bazei de date. Astfel utilizatorul nu va fi nevoit sa scrie comenzi in linia de comanda, ci numai sa apese anumite butoane.

Site-ul va fi dezvoltat cu ajutorul platformei WAMP disponibila gratuit pe Internet.

Capitolul I – Notiuni teoretice despre baze de date. Baze de date relationale

Definiția bazei de date

În sensul cel mai larg, o bază de date este o colecție de date corelate din punct de vedere logic, care reflectă un anumit aspect al lumii reale și este destinată unui anumit grup de utilizatori. În acest sens, bazele de date pot fi create și menținute manual sau computerizat, așa cum este majoritatea bazelor de date folosite în momentul de față. O definiție într-un sens mai restrâns a unei baze de date este următoarea:

Baza de date poate fi privită ca o colecție de fișiere interconectate care conțin nucleul de date necesare unui sistem informatic. Astfel, poate fi considerată drept un model al unor aspecte ale realității unei unități economice, modelată prin intermediul datelor. Diferitele obiecte din cadrul realității ce prezintă interes sunt denumite clase sau entități. Pentru aceste obiecte sunt achiziționate și memorate date referitoare la diferite caracteristici (atribute). Baza de date se constituie ca un ansamblu intercorelat de colecții de date, prin care se realizează reprezentarea unei realități.

Datele constituie orice mesaj primit de un receptor, sub o anumită formă. Informațiile reprezintă cantitatea de noutate adusă de un mesaj din exterior (realitate).

Un fișier este un ansamblu de înregistrări fizice, omogene din punct de vedere al conținutului și al prelucrării.

O înregistrare fizică este o unitate de transfer între memoria internă și cea externă a calculatorului.

O înregistrare logică este unitatea de prelucrare din punct de vedere al programului utilizator.

O înregistrare se compune din câmpuri (atribute) care descriu anumite aspecte ale realității.

Câmpurile sunt înregistrări logice.

O bază de date trebuie să asigure:

• abstractizarea datelor (baza de date fiind un model al realității),

• integrarea datelor (baza de date este un ansamblu de colecții de date intercorelate, cu redundanță controlată),

• integritatea datelor (se referă la corectitudinea datelor încărcate și manipulate astfel încât să se respecte restricțiile de integritate),

• securitatea datelor (limitarea accesului la baza de date),

• partajarea datelor (datele pot fi accesate de mai mulți utilizatori, eventual în același timp),

• independența datelor (organizarea datelor să fie transparentă pentru utilizatori, modificările în baza de date să nu afecteze programele de aplicații).

De obicei o bază de date este memorată într-unul sau mai multe fișiere. Bazele de date sunt manipulate cu ajutorul sistemelor de gestiune a bazelor de date.

Sistemele de gestiune a bazelor de date (în limba engleză "database management system" – SGDB) reprezintă totalitatea programelor utilizate pentru crearea, interogarea și întreținerea unei baze de date. Include două categorii de module: module care sunt comune cu cele ale sistemelor de operare ale calculatoarelor și module cu funcții specifice bazei de date. Subsistemele monitor conțin programele de control al perifericelor și sistemul de gestiune a fișierelor. Subsistemele externe sunt alcătuite din procesorul de definiție și programul de administrare. Alături de acestea există programe de descriere a bazei de date și cereri de prelucrare.Între utilizator și sistem există două interfețe: definirea bazei de date și utilizarea bazei de date. Definirea unei baze de date se execută sub controlul procesorului de definiție (PD), capabil să prelucreze programe de descriere, formulate folosind limbaje specializate cunoscute sub denumirea de limbaje de definiție a datelor (LDD).

Cel mai răspândit tip de baze de date este cel relațional, în care datele sunt memorate în tabele. Pe lânga tabele, o bază de date relațională mai poate conține: indecși, proceduri stocate, declanșatori, utilizatori și grupuri de utilizatori, tipuri de date, mecanisme de securitate și de gestiune a tranzacțiilor etc. Alte tipuri de baze de date sunt modelul ierarhic, modelul orientat pe obiecte și, mai nou, modelul XML.

Definiția bazei de date relațională

În cazul bazelor de date relaționale structura de bază a datelor este aceea de relație – tabel. Limbajul SQL (Structured Query Language) este specializat în comenzi de manipulare la nivel de tabel. Termenul relațional a fost introdus de un cercetător al firmei IBM dr. E. F. Codd în 1969 cel care a enunțat cele 13 reguli de bază necesare pentru definerea unei baze de date relaționale. Baza de date relațională reprezintă o mulțime structurată de date, accesibile prin calculator, care pot satisface în timp minim și într-o manieră selectivă mai mulți utilizatori.

SGBD au cunoscut o largă răspândire, datorită modelului simplu, relațional pe care îl utilizează:

Datele se prezintă sub forma unei colecții de relații

Fiecare relație are forma unui tabel

Rândurile (înregistrările) tabelului reprezintă entități.

Coloanele (câmpurile) tabelului sunt atribute/proprietăți ale acestor entități.

Fiecare tabel are un set de atribute, care împreună reprezintă o „cheie” care definește fiecare entitate în mod unic.

Modelul relațional este cel mai utilizat dintre modelele de date existente (modele ierarhice, modele rețtea, modele orientate pe obiect). Față de modele ierarhic și rețea, modelul relațional prezintă câteva avantaje:

propune structuri de date ușor de utilizat;

ameliorează independența logică și fizică;

pune la dispoziția utilizatorilor limbaje neprocedurale;

optimizează accesul la date;

imbunătățeste confidențialitatea datelor.

Un model relational de baze de date cuprinde trei componente principale:

structura datelor prin definirea unor domenii (valori atomice) si a relatiilor “n” (atribute, tupluri, chei primare);

integrarea datelor prin impunerea unor restrictii;

prelucrarea datelor prin operatii din algebra relationala sau calcul relational.

Modelul relațional se bazează pe noțiunea matematică de relație (din teoria mulțimilor) definită ca o submulțime a produsului cartezian a unei liste finite de mulțimi numite domenii. Elementele unei relații se numesc tupluri (sau n-cupluri), iar numărul de domenii din produsul cartezian se numește arietatea relatiei (FOTACHE 1997, 102).

De obicei relațiile sunt reprezentate sub forma unor tabele în care fiecare rând reprezintă un tuplu și fiecare coloană reprezintă valorile tuplurilor dintr-un domeniu dat al produsului cartezian.

În reprezentarea sub formă de tabel a unei relații, coloanelor și domeniilor corespunzătoare lor, li se asociază nume intitulate atribute. Multimea numelor atributelor unei relații se numește schema relațională.Mulțimea tuturor schemelor relaționale corespunzătoare unei aplicații se numește schema bazei de date relaționale, iar conținutul curent al relațiilor, la un moment dat, se numește bază de date relațională.

Importanța bazelor de date

Avantajele oferite de sistemele de baze de date sunt următoarele:

Compactitate ridicată: volumul ocupat de sistemele de baze de date este mult mai redus decât volumul ocupat de documente scrise sau de fișiere necorelate.

Viteza mare de regăsire și actualizare a informațiilor.

Redundanța scazută a datelor memorate, care se obține prin partajarea datelor între mai mulți utilizatori și aplicații. În stocarea pe fișe sau în fișiere a datelor, fiecare aplicație conținea propriile seturi de date. În sistemele de baze de date, mai multe aplicații pot folosi date comune, memorate o singură dată. De exemplu, o aplicatie de personal si o aplicatie de rezultate la examene dintr-o universitate care exploatează o singura bază de date, pot folosi aceleași informații referitoare la structurarea facultăților și a secțiilor.

Posibilitatea de introducere a standardelor privind modul de stocare a datelor, ceea ce permite interschimbul informațiilor între diferite organizații.

Menținerea integrității datelor prin politica de securitate (drepturi de acces diferențiate în funcție de rolul utilizatorilor), prin gestionarea tranzacțiilor și prin refacerea datelor în caz de funcționare defectuoasă a diferitelor componente hardware sau software.

Independența datelor față de suportul hardware utilizat. Sistemele de gestiune a bazelor de date oferă o vedere (“view”) externă a datelor, care nu se modifică atunci când se schimbă suportul de memorare fizic, ceea ce asigură imunitatea structurii bazei de date și a aplicațiilor la modificări ale sistemului hardware utilizat.

Realizarea unei baze de date

Deși au fost publicate destule cărți dedicate proiectării bazelor de date, subiectul continuă să fie departe de epuizare. Chiar dacă unii autori s-au străduit să aducă rigurozitate, uneori cu prețul unei anume rigidități, proiectarea bazelor de date rămâne preponderent o artă și mai puțin o știință. Problema proiectarii unei baze de date ține de elaborarea unei structuri logice și a alteia fizice în vederea întâmpinării nevoilor informaționale ale utilizatorilor într-o organizație, pentru un set definit de aplicații.

Realizarea bazelor de date relaționale constă în luarea unor decizii cu privire la modelarea unor sisteme din lumea reală într-o bază de date. Există mai multe etape în procesul de realizare a unei baze de date: proiectarea conceptuală, proiectarea logică și proiectarea fizică.

Proiectarea conceptuală a bazei de date constă în construirea reprezentării conceptuale a bazei de date, care include identificarea tipurilor importante de entități, relații, atribute și prezintă următorii pași: identificarea tipurilor de entități (E), identificarea tipurilor de relații (R), identificarea și asocierea atributelor (A) cu tipurile de E sau R, determinarea domeniilor atributelor, determinarea atributelor chei candidat și chei primare, specializarea și generalizarea tipurilor de entități.

Proiectarea logică a bazei de date constă în transpunerea reprezentării conceptuale în structura logică a bazei de date, care include proiectarea relațiilor; avem parte de următoarele etape: transpunerea modelului conceptual local în modelul de date logic local (eliminarea relațiilor M:N prin înlocuirea cu relații de tip 1:M sau alte metode, eliminarea relațiilor complexe prin înlocuirea cu relații de tip 1:M, eliminarea relațiilor recursive prin înlocuirea cu relații dependente, eliminarea atributelor multiple prin înlocuirea cu relații dependente, reexaminarea relațiilor 1:1, eliminarea relațiilor redundante), extragerea relațiilor din modelul de date logic local pentru a reprezenta entitățile și relațiile, normalizarea relațiilor, validarea modelului conform tranzacțiilor utilizatorului pentru a garanta că acesta acceptă și rezolvă operațiile cerute de către model, definirea constrângerilor de integritate.

Proiectarea fizică a bazei de date reprezintă implementarea fizică a structurii logice într-o capacitate de stocare secundară corespunzătoare SGBD-ului țintă.

Ciclul de viață al bazelor de date se poate structura pe următoarele etape:

1. analiza cerințelor;

2. proiectarea logică, ce se materializează în schema globală ce conține datele și relațiile dintre ele, fiind derulată astfel :

a) modelarea E-R;

b) integrarea perspectivelor utilizator;

c) conversia diagramelor E-R în tabele;

d) normalizarea tabelelor ;

3. proiectarea fizică: selectarea indexurilor, metodelor de acces, cluster-elor de date; tot aici, se include și denormalizarea;

4. distribuirea datelor, materializată în schema de fragmentare și schema de alocare a datelor;

5. implementarea, monitorizarea și modificarea ulterioară a bazei de date. Și aici apar dubii legate de modul de derulare a normalizării, o dată ce prin conversia diagramelor E-R se obțin deja tabelele relaționale.

Modelul Diagramelor Entitate-Relație (Entity Relationship Diagram)

Cel mai utilizat model conceptual de nivel înalt este modelul Entitate-Asociere (E-A) care reprezintă schema conceptuală de nivel înalt a bazei de date prin mulțimi de entități și asocieri dintre acestea. Dezvoltarea acestui model, astfel încât să permită extinderea tipurilor de entități, este cunoscută sub numele de model Entitate-Asociere Extins (E-AE). Proiectarea modelului E-A sau al modelului E-AE este, de regulă, una din primele etape în proiectarea bazelor de date, etapă numită proiectarea schemei conceptuale.

Modelul Entitate-Asociere („Entity-Relationship Model”), introdus în 1976 de P.S. Chen, este un model conceptual de nivel înalt al unei baze de date, care definește mulțimile de entități și asocierile dintre ele, dar nu impune nici un mod specific de structurare și prelucrare (gestiune) a datelor.

Elementele esențiale ale modelului Entitate-Asociere folosit în proiectarea bazelor de date sunt entitățile (“entities”) și asocierile dintre acestea (“relationships”).

O entitate (“entity”) este „orice poate fi identificat în mod distinctiv”; o entitate se referă la un aspect al realității obiective care poate fi deosebit de restul universului și poate reprezenta un obiect fizic, o activitate, un concept, etc. Orice entitate este descrisă prin atributele sale. Un exemplu de entitate pentru baza de date a unui operator de telefonie mobilă este un abonat care reprezintă o persoană care folosește serviciile oferite de operator.

Un atribut (“attribute”) este o proprietate care descrie un anumit aspect al unei entități. În cazul entității abonat, acesta poate avea mai multe atribute ca de exemplu: numele, numărul de telefon, codul pe care îl stabilește operatorul iar acestea reprezintă atribute pentru identificarea abonatului. Alte atribute ar putea fi tipul de abonament, costul facturii sau starea de plată a facturii care reprezintă atribute legate de activitatea acestuia ca abonat.

Atributele prin care este descrisă o entitate se aleg pe baza criteriului relevanței relativ la domeniul de interes pentru care se definește modelul respectiv, astfel încât să asigure diferențierea acelei entităti față de restul universului.

Toate entitățile similare, care pot fi descrise prin aceleași atribute, aparțin unui același tip de entitate (“entity type”), iar colecția tuturor entităților de același tip dintr-o bază de date constituie o mulțime de entitati (“entities set”). In general, in modelul E-A se foloseste aceeasi denumire atât pentru un tip de entitate cât și pentru mulțimea entităților de acel tip.

În proiectarea bazelor de date se consideră două categorii de entități: entități normale (puternice, obișnuite – “regular entities”) și entități slabe (dependente – “weak entities”). Entitățile normale au o existența proprie în cadrul modelului, în timp ce entitățile slabe nu pot exista decât dacă există o entitate normală (puternică) cu care sunt asociate.

În proiectarea bazelor de date se definesc asocieri între mulțimile de entități componente, pentru a reprezenta anumite aspecte ale realității pe care baza de date o modelează.

O asociere (“relationship”) este o corespondență între entități din două sau mai multe mulțimi de entități. Gradul unei asocieri este dat de numărul de mulțimi de entități asociate. Asocierile pot fi binare (de gradul 2, între 2 mulțimi de entități) sau multiple (între k mulțimi de entități, k > 2).

Asocierile binare sunt, la rândul lor, de trei categorii, după numărul elementelor din fiecare dintre cele doua mulțimi puse în corespondența de asocierea respectivă. Fiind date două mulțimi de entități, E1 și E2, se definesc următoarele categorii de asocieri binare:

Asocierea “unul-la-unul” (one-to-one) este asocierea prin care unui element (entitate) din mulțimea E1 îi corespunde un singur element din mulțimea E2, și reciproc; se notează cu 1:1.

Asocierea „unul-la-multe” (one-to-many) este asocierea prin care unui element din mulțimea E1 ii corespund unul sau mai multe elemente din mulțimea E2, dar unui element din E2 îi corespunde un singur element în mulțimea E1; se notează cu 1:N.

Asocierea „multe-la-multe” (many-to-many) este asocierea prin care unui element din mulțimea E1 îi corespund unul sau mai multe elemente din mulțimea E2 și reciproc; se notează cu M:N. Cardinalitatea (multiplicitatea) unei asocieri față de o mulțime de entități (cardinality, multiplicity) este numărul maxim de elemente din acea mulțime care pot fi asociate cu un element din altă mulțime a asocierii.

Fig.5.1 Categorii de asociere între două entități: a – asociere 1:1; b – asociere 1:N; c – asociere M:N

Cardinalitatea (multiplicitatea) unei asocieri față de o mulțime de entități („cardinality”, „multiplicity”) este numărul maxim de elemente din acea mulțime care pot fi asociate cu un element din altă mulțime a asocierii.

De exemplu, asocierea 1:N dintre mulțimile E1 si E2 prezintă multiplicitatea 1 față de mulțimea E1 și multiplicitatea N (se înțelege o valoare oarecare N > 1) față de mulțimea E2. Raportul dintre valorile cardinalităților unei asocieri binare față de cele doua mulțimi de entități se numește raport de cardinalitate (cardinality ratio). Se poate observa ca cele trei categorii de asocieri descrise mai sus diferă între ele prin raportul de cardinalitate.

Asocierile multiple (k-are, k > 2) prezintă câte un raport de cardinalitate pentru fiecare pereche de mulțimi de entități pe care le asociază. O asociere între două sau mai multe mulțimi de entități este, în același timp, o asociere între tipurile de entități corespunzatoare.

Sunt de remarcat câteva caracteristici generale ale modelului E-A:

– Modul de stabilire a tipurilor de entități și a asocierilor dintre acestea nu este unic, deoarece granița dintre entități și asocieri nu este, în general, una bine precizată. Aceeași funcționalitate se poate obține printr-o varietate de diagrame E-A, depinzând de felul în care proiectantul dezvoltă modelul conceptual. O asociere poate fi considerată și ca un tip de entitate.

– În modelul E-A, tipul de entitate (și mulțimea de entități corespunzatoare) semnifică un substantiv, în timp ce o asociere semnifică un verb. Bineînțeles, nu este obligatoriu ca numele dat unei asocieri sa fie un verb (și, de cele mai multe ori, nici nu este), dar o asociere reprezintă o interacțiune între tipurile de entități (și mulțimile de entități corespunzătoare), care poate fi exprimată printr-un verb.

– Modelul E-A nu precizează modul cum sunt realizate asocierile între mulțimile de entități. Acest aspect depinde de modelul de date specializat utilizat pentru definirea bazei de date. De exemplu, în modelele ierarhic și rețea, asocierile sunt realizate explicit, prin pointeri de la o entitate la entitățile asociate, în timp ce în modelul relațional asocierea se realizează prin egalitatea valorilor unor atribute comune ale entităților (chei).

Modelul Entitate-Asociere Extins (Enhanced Entity-Relationship Model) permite definirea de subtipuri ale unui tip de entități, care moștenesc atribute de la tipul de entitate pe care îl extind (și care, în acest context, se numeste supertip) și au în plus atribute specifice semnificației lor. Prin definirea tipurilor și a subtipurilor de entități se pot crea ierarhii de tipuri de entități pe mai multe niveluri.

Odată cu dezvoltarea sistemelor de baze de date, domeniile în care acestea se folosesc au devenit tot mai numeroase, că, de exemplu: telecomunicațiile, proiectarea tehnologică, sistemele de informații geografice, seviciul Web, etc. Tipurile de entități definite în astfel de baze de date sunt mult mai complexe și pentru reprezentarea lor cât mai intuitivă și mai compactă au fost propuse mai multe concepte noi, care au fost introduse în modelul E-A extins.

Modelul E-A extins se reprezintă printr-o diagrama E-A extinsă. Ierarhiile de tipuri se pot crea prin specializare sau generalizare.

Specializarea (specialization) este un proces de abstractizare a datelor prin care, pornind de la un tip de entitate dat, se definesc unul sau mai multe subtipuri, diferențiate între ele în funcție de rolul specific pe care îl au în modelul de date.

Generalizarea (generalization) este procesul de abstractizare invers specializării, prin care se crează un supertip de entitate pornind de la mai multe tipuri de entități. Pentru definirea unei generalizări, se identifică atributele comune ale mai multor tipuri de entități și aceste atribute vor caracteriza supertipul de entitate, iar atributele care diferă de acestea rămân specifice fiecărui tip.

Normalizarea bazei de date

Normalizarea este o tehnică de proiectare a bazelor de date prin care se elimină (sau se evită) anumite anomalii și inconsistențe a datelor. O bază de date bine proiectată nu permite astfel ca datele să fie redundante, adică aceeași informație să se găsească în locuri diferite, sau să memorezi în baza de date, informații care se pot deduce pe baza altor informații memorate în aceeași bază de date. Anomaliile care pot să apară la o bază de date nenormalizată sunt următoarele:

– anomalii la actualizarea datelor – un operator de telecomunicații încheie un contract mare cu o firmă care are un număr mare de angajați ce devin clienți și decide să salveze în tabela „CLIENT” informația despre adresa firmei la care lucrează acești angajați. Dacă adresa firmei se modifică, atunci administratorul bazei de date va trebui actualizeze toate înregistrările corespunzătoare angajaților firmei din tabela „CLIENT”. Dacă această modificare nu se face cu succes, unele dintre înregistrări rămânând cu vechea adresă, apare din nou o inconsistență a datelor.

– anomalii de inserare – în exemplul anterior, nu vom putea memora adresa unei firme, lucru inacceptabil dacă dorim să avem informații despre zona în care se află firma, având în vedere că acolo se pot gasi potențiali noi clienti.

– anomalii de ștergere – să presupunem că într-o tabelă memorăm următoarele informații: codul opțiunii activate, codul clientului, codul angajatului care a activat opțiunea. La un moment dat, nici un client nu mai dorește să activeze o anumită opțiune. Ștergând toate înregistrările corespunzătoare opțiunii, nu vom mai putea ști niciodată ce angajat a facut activarea opțiunii.

Edgar Codd a definit primele trei forme normale 1NF, 2NF și 3NF. Ulterior s-au mai definit formele normale 4NF, 5NF, 6NF care însă sunt rar folosite în proiectarea bazelor de date.

Prima forma normala

O entitate se găsește în prima formă normală dacă și numai dacă:- nu există atribute cu valori multiple;- nu există atribute sau grupuri de atribute care se repetă. Cu alte cuvinte toate atributele trebuie să fie atomice, adică să conțină o singură informație.

A doua forma normala

O entitate se găsește în a doua formă normală dacă și numai dacă se găsește în prima formă normală și în plus orice atribut care nu face parte din UID (unique identifier) va depinde de întregul UID nu doar de o parte a acestuia

A treia forma normala

O entitate se găsește în a treia formă normală dacă și numai dacă se găsește în a doua formă normală și în plus nici un atribut care nu este parte a UID-ului nu depinde de un alt atribut non-UID. Cu alte cuvinte nu se acceptă dependențe tranzitive, adică un atribut să depindă de UID în mod indirect.

Capitolul II – Proiectarea bazelor de date

Scenariul de construcție al bazei de date

Un operator de telecomunicații are nevoie de o bază de date pentru a-și putea gestiona toți clienții. Un client înscris în rețea poate fi: fie client prepay, fie client postpay sau ambele (să aibă și o cartelă prepay și un abonament în același timp). Pentru client este important să fie reținute următoarele date: Nume, Prenume, CNP, Data Nașterii, Adresă, Mail și Data înregistrării în rețea. De asemenea, un abonat poate avea mai multe numere de telefon. Pentru clienții prepay vom trata fiecare număr de telefon că un client separat, chiar dacă un client real poate deține mai multe cartele prepay.

De asemenea, când este înscris în rețea un client postpay este indicat să se rețină și ID-ul, numele și prenumele angajatului care a închis contractul pentru a putea recompensa trimestrial angajații care înscriu în rețea cele mai multe abonamente.

Este foarte important a se reține informațiile despre numerele de telefon asignate clienților. Aceste numere de telefon se vor împarți în numere prepay și numere postpay. Pentru un număr de telefon prepay trebuiesc reținute numărul de telefon (MSISDN-ul), creditul disponibil al acestuia, precum și dacă acesta poate sau nu să efectueze trafic în roaming. Pentru un număr de telefon postpay trebuiesc reținute numărul de telefon (MSISDN-ul), dacă acesta este restant sau nu și de asemenea, dacă acesta poate sau nu să efectueze trafic în roaming.

Se dorește ca toate serviciile oferite clienților să fie stocate în baza de date, atât cele prepay cât și cele postpay.

Pentru serviciile prepay se vor reține următoarele informații: numele serviciului, numărul de minute naționale alocate, numărul de minute în rețea alocate, numărul de sms-uri naționale alocate, numărul de sms-uri în rețea alocate, numărul de MB alocați, prețul serviciului și valabilitatea acestuia.

Pentru serviciile postpay se vor reține următoarele informații: numele serviciului, numărul de minute naționale alocate, numărul de minute în rețea alocate, numărul de sms-uri naționale alocate, numărul de sms-uri în rețea alocate, numărul de MB alocați și prețul serviciului.

De asemenea, se dorește a se reține o bază de date cu toate voucherele emise pentru fidelizarea clienților. Un voucher este unic și poate fi folosit o singură dată de către un client.

Realizarea diagramei E-R

Primul pas în realizarea unei aplicații de baze de date este analiza datelor și realizarea unei scheme conceptuale (model conceptual) al acestor date.

În această etapă sunt analizate natura și modul de utilizare a datelor. Sunt identificate datele care vor trebui memorate și procesate, se împart aceste date în grupuri logice și se identifică relațiile care există între aceste grupuri.

Analiza datelor este un proces uneori dificil, care necesită mult timp, însă este o etapă absolut obligatorie. Fără o analiză atentă a datelor și a modului de utilizare a acestora, vom realiza o bază de date care putem constata în final că nu întrunește cerințele beneficiarului. Costurile modificării acestei baze de date este mult mai mare decât costurile pe care le-ar fi implicat etapa de analiză și realizare a modelului conceptual. Modificarea modelului conceptual este mult mai ușoară decât modificarea unor tabele deja existente, care eventual conțin și o mulțime de date. Ideea de bază a analizei datelor și construirii modelului conceptual este "să măsori de două ori și să tai o singură dată".

Informațiile necesare realizării modelului conceptual se obțin folosind metode convenționale precum intervievarea oamenilor din cadrul organizației și studierea documentelor folosite.

Odată obținute aceste informații ele trebuiesc reprezentate într-o formă convențională care să poată fi ușor înțeleasă de toată lumea. O astfel de reprezentare este diagrama entități-relații, numită și harta relațiilor, sau ERD-ul (Entity Relationship Diagram). Aceste scheme sunt un instrument util care ușurează comunicarea dintre specialiștii care proiectează bazele de date și programatori pe de o parte și beneficiari, pe de altă parte. Aceștia din urmă pot înțelege cu ușurință o astfel de schemă, chiar dacă nu sunt cunoscători în domeniul IT.

În concluzie putem sublinia câteva caracteristici ale ERD-urilor:

– sunt un instrument de proiectare

– sunt o reprezentare grafică a unui sistem de date

– oferă un model conceptual de înalt nivel al bazelor de date

– sprijină înțelegerea de către utilizatori a datelor și a relațiilor dintre acestea

– sunt independente de implementare.

In urma acestei analize a datelor din scenariu se extrag urmatoarele entități:

CLIENT

MSISDN_PREPAY

MSISDN_POSTPAY

SERVICIU_PREPAY

SERVICIU_POSTPAY

VOUCHER

ANGAJAT

Atributele acestor entități vor fi:

CLIENT:

id -> identificatorul clientului în baza de date

cnp -> codul numeric personal al clientului

nume -> numele clientului

prenume -> prenumele clientului

data_nașterii -> data de naștere a clientului

adresa -> adresa clientului

data_înregistrării -> data înregistrării în rețea a clientului

mail -> adresa de poșta electronică a clientului

MSISDN_PREPAY:

id -> identificatorul numărului de telefon prepay

nr_tel -> numărul de telefon (MSISDN)

credit -> creditul disponibil în euro

roaming -> starea serviciului roaming

MSISDN_POSTPAY:

id -> identificatorul numărului de telefon postpay

nr_tel -> numărul de telefon (MSISDN)

restant -> starea plații serviciului

roaming -> starea serviciului roaming

SERVICIU_PREPAY

id -> identificatorul numărului de telefon postpay

nume -> numele serviciului

min_nat -> numărul de minute alocate în rețelele naționale

min_retea -> numărul de minute alocate în rețeaua de apartenență

sms_nat -> numărul de mesaje alocate în rețelele naționale

sms_retea -> numarul de mesaje alocate în rețeaua de apartenență

nr_mb -> volumul de trafic de internet alocat

pret -> prețul serviciului

valabilitate -> valabilitatea serviciului

SERVICIU_POSTPAY

– id -> identificatorul numărului de telefon postpay

– nume -> numele serviciului

– min_nat -> numărul de minute alocate în rețelele naționale

– min_rețea -> numărul de minute alocate în rețeaua de apartenență

– sms_nat -> numărul de mesaje alocate în rețelele naționale

– sms_rețea -> numărul de mesaje alocate în rețeaua de apartenență

– nr_mb -> volumul de trafic de internet alocat

– preț -> prețul serviciului

ANGAJAT

id -> identificatorul angajatului

nume -> numele angajatului

prenume -> prenumele angajatului

VOUCHER

id -> identificatorul voucher-ului

cod -> codul voucher-ului

valoare -> valoarea voucher-ului

data_folosire -> data la care clientul a folosit voucher-ul

Conventii de ridabilitate: Se aplica conventiile de scriere a ERD-ului:

Entitatea se scrie cu majuscule, singular în interiorul unui dreptunghi cu vârfurile rotunjite.Atributele se scriu cu litere mici , având în față unul din semnele #,*,o(UID, obligatoriu, opțional).Orientarea liniilor este de la V la E și de sus în jos, evitând intersecția. Se pot folosi subdiagrame de explicare a diagramelor complexe, și explicarea entităților cu multe atribute.

Pornind de la aceste informații s-a realizat următoarea schiță a diagramei E-R:

Convenții de reprezentare a relațiilor

În cadrul diagramei entități-relații, o relație va fi reprezentată printr-o linie ce unește cele două entități.

Deoarece o relație este bidirecțională, linia ce unește cele două entități este compusă din două segmente distincte, câte una pentru fiecare entitate. Tipul segmentului ce pleacă de la o entitate ne va indică optionalitatea relației dintre această entitate și entitatea aflată în cealaltă parte a relației. Dacă acest segment este continuu este vorba de o relație obligatorie, o linie întreruptă indică o relație opțională.

De exemplu în figura 1 segmentul ce pleacă de la entitatea CLIENT fiind întreruptă înseamnă că un client poate deține un cod promoțional (voucher), adică relația este opțională. Segmentul ce pleacă dinspre entitatea VOUCHER este continuă, deci un cod promoțional trebuie să fie folosit de către un client.

Figura 1 Reprezentarea relatiilor

Modul în care o linie se termină spre o entitate este important. Dacă se termină printr-o linie simplă, înseamnă că o instanță și numai una a acestei entități este în relație cu o instanță a celeilalte entități.

Dacă linia se termină cu trei linii (picior de cioară) înseamnă că mai multe instanțe ale entității pot corespunde unei instanțe a celeilalte entități. În exemplul anterior linia trasată de la entitatea CLIENT la entitatea VOUCHER se termină cu piciorul de cioară, înseamnă că unei instanțe a entității CLIENT îi corespund mai multe instanțe ale entității VOUCHER, adică un client are unul sau mai multe coduri promoționale.

Având în vedere diagrama expusă mai sus și ținând cont de scenariul bazei de date se vor crea următoarele legături între entitățile bazei de date:

Maparea relațiilor

Maparea relatiilor one-to-one

Dându-se două entități A și B legate între ele printr-o relație one-to-one, este evident că putem include cheia primară A în cadrulul tabelei B, dar putem proceda la fel de bine și invers, incluzând cheia primară a tabelei B în cadrul tabelei A, deoarece fiecărei instanțe a entității A îi corespunde cel mult o instanță a entității B, dar și invers, oricărei instanțe a entității B îi corespunde cel mult o instanță a entității A

Decizia depinde de specificul afacerii modelate. Daca baza de date este destinata evidentei elementelor din entitatea A atunci este indicat sa se adopte prima varianta, dacă însă prezinta mai mult interes evidenta elementelor tabelei B, atunci idicat sa se adopta varianta a doua.

Uneori este convenabil să memorăm cheia străină în ambele părți ale relației. Spre exemplu, atunci cand este ne intereseaza in mod egal tinerea evidentei elementelor ambelor entitati.

Maparea relatiilor one-to-many

Vom considera exemplul prezentat mai sus în Figura 1.

Figura 10.2.1. Maparea relațiilor one-to-many

Relația dintre cele două entități se citește în felul următor:

Fiecare CLIENT poate deține unul sau mai multe VOUCHER-e

Fiecare VOUCHER este deținut de un CLIENT și numai unul

Se observă că nu se pot memora voucherele ce sunt folosite de un client în cadrul tabelei CLIENT, deoarece acest lucru ar conduce la introducerea unei coloane cu valori multiple, fapt ce ar contrazice prima formă normală. De asemenea, se observă că nu există nicio restricție în aplicarea procedeului în sens invers: astfel vom memora identificatorul fiecărui client în tabela VOUCHER.

Pornind de la aceste prezumții se construiesc următoarele tabele: CLIENT

VOUCHER

Un aspect foarte important al maparii relațiilor one to many este acela că dacă relația pe partea many este opțională atunci și coloanele cheii străine vor fi opționale. Transpunând această regulă peste exemplul de mai sus rezultă posibilitatea câmpului Id_client de a lua valoarea NUL în momentul în care voucherul respectiv nu a fost folosit de nimeni.

În general, la maparea unei relații de tip one-to-many, vom introduce în tabela corespunzătoare entității de pe partea many a relației cheia primară a entității de pe partea one a relației. Câmpurile astfel introduse se vor numi cheie străină (foreign key).

Așadar:

– cheia străină a unei tabele este cheia primară din tabela referințăƒ

– cheia străinムeste întotdeauna introdusムîn tabela corespunzătoare entității din partea many a relației.

In cadrul schemei de mai sus, se observa apariția unei relații M:N („Many-to-Many”). Aceasta relație nu poate apărea decât în această faza incipientă a proiectării bazei de date întrucat ea nu se poate mapa.

Maparea relatiilor many-to-many

Pentru a prelucra o relație M:N se urmează următorii pași:

1) se găsește entitatea de intersecție, pentru cazul de mai sus vom introduce entitate ACT_OPT_PREPAY (activare optiune prepay).

2) crearea noilor relații

– opționalitatea: relațiile care pleacă din entitatea de intersecție sunt întotdeauna obligatorii în această parte. În partea dinspre entitățile originale, relațiile vor păstra opționalitatea relațiilor inițiale.

– cardinalitatea: ambele relații sunt de tip one-to-many, iar partea cu many va fi întotdeauna înspre entitatea de intersecție.

– numele noilor relații

3) adăugarea de atribute în cadrul entității de intersecție, dacă acestea există. În exemplul nostru ne intereseaza data la care s-a activat o optiune.

4) stabilirea identificatorului unic pentru entitatea de intersecție: dacă entitatea de intersecție nu are un identificator unic propriu, atunci acesta se poate forma din identificatorii unici ai entităților inițiale la care putem adăuga atribute ale entității de intersecție.

În exemplul nostru, identificatorul unic al entității de intersecție este format din id-ul numarului de telefon prepay, id-ul optiunii prepay si id-ul activarii.

5) Faptul că identificatorul unic al unei entități preia identificatorul unic din altă entitate cu care este legată este reprezentat grafic prin bararea relației respective, înspre entitatea care preia UID-ul celeilalte entități.

Maparea relatiilor barate

Relațiile barate sunt mapate ca cheie străină în tabela aflată în partea many a relației, la fel ca la maparea oricărei relații one-to-many. Bara de pe relație exprimă faptul că acele coloane ce fac parte din cheia străină vor devenii parte a cheii primare a tabelei din partea many a relației barate.

Spre exemplu, in figura 2, cheia primara a tabelei ACT_OPT_PREPAY va fii formata din coloana „id” corespunzatoare acestei tabele, din coloana „id” corespunzatoare campului MSISDN_PREPAY si din coloana „id” corespunzătoare câmpului SERVICIU_PREPAY. Fiecare coloana „id” în coloana proprie reprezintă cheia primară a tabelei.

Având în vedere aceste reguli se construiește diagrama E-R finală pe baza căreia se va dezvolta întreaga bază de date.

Capitolul III – Proiectarea software a bazelor de date. WAMP.

Tipuri de date MySql

Când se crează un tabel în MySQL, trebuie definit tipul de date pe care fiecare coloană îl va conține. Există trei tipuri principale: Text (strings), Numere, Data și Ora; și două tipuri secundare: Liste predefinite și Date binare.

Tipul de date dictează ce informație poate fi stocată și cum, acesta influențează și performanță generală a bazei de date.

Tabelul de mai jos listează tipurile de date folosite pentru MySQL, cu o scurtă descriere și cât spațiu ocupă.

Parametri (lungime, decimal) sunt opționali, dar pentru motive de performanță, ar trebui specificați pentru a restricționa câtă informație să fie stocată în oricare din coloane. Bazele de date sunt de obicei mai rapide când lucrează cu coloane care au mărimea fixată.

Plecând de la diagrama ERD finală au putut fi extrase următoarele tabele:

Parametrii (lungime, decimal) sunt opționali, dar pentru motive de performanță, ar trebui specificați pentru a restricționa câtă informație să fie stocată în oricare din coloane. Bazele de date sunt de obicei mai rapide când lucrează cu coloane care au mărimea fixată.

Plecând de la diagrama ERD finală au putut fi extrase următoarele tabele:

Angajat

Client

Msisdn_Postpay

Serviciu_Postpay

Msisdn_Prepay

Serviciu_Prepay

Act_Opt_Prepay

Voucher

Reguli de integritate

Detalierea caracteristicilor pe care trebuie să le prezinte un SGBD pentru a fi considerat relațional s-a făcut de E. F. Codd în 1985 sub forma a 13 reguli. Una dintre aceste reguli precizează că restricțiile de integritate trebuie să poată fi definite în limbajul utilizat de SGBD pentru definirea datelor.

Regulile de integritate garantează că datele introduse în baza de date sunt corecte și valide. Aceasta înseamnă că dacă există orice o regulă sau restricție asupra unei entități, atunci datele introduse în baza de date respectă aceste restricții. În MySQL, regulile de integritate se definesc la crearea tabelelor folosind constrângerile. Dar asupra acestora vom reveni în partea a doua a manualului.

Tipurile de reguli de integritate sunt următoarele:

Integritatea entităților – indică faptul că nici o coloană ce face parte din cheia primară nu poate avea valoarea NUL. În plus, pentru fiecare înregristrare, cheia primară trebuie să fie unică.

Integritatea de domeniu – acest tip de reguli permite ca într-o anumită coloană se introducă doar valori dintr-un anumit domeniu. De exemplu putem impune ca valoarea unui VOUCHER să fie cuprinsa între 1 și 50 EURO.

Integritatea referențială – este o protecție care asigură ca fiecare valoare a cheii străine să corespundă unei valori a cheii primare din tabela referită. De exemplu, referindu-ne la tabelele VOUCHER și CLIENT, corespunzătoare ERD-ului din figura 1, id este cheie primară în tabela CLIENT, iar în tabela VOUCHER, id devine cheie străină. Astfel valoarea câmpului id din cadrul tabelei VOUCHER corespunzătoare unui anumit cod promotional trebuie să se regăsească printre valorile câmpului id din tabela CLIENT, altfel ar însemna că voucherul respectiv a fost utilizat de un client inexistent ( vezi Figura1 ).

Situații de încălcare a integrității referențiale pot apărea:

la adăugarea unei noi înregistrări în baza de date, se poate încerca introducerea unor valori invalide pentru câmpurile cheii străine;

la actualizarea bazei de date;

la ștergerea unei înregistrări. De exemplu se șterge înregistrarea corespunzătoare unui anumit client (clientul paraseste reteaua). Înregistrările voucher-elor care au fost utilizate de acel client vor încălca integritatea referențială, deoarece se vor referi la un client care nu mai există. Soluțiile posibile sunt ca la ștergerea unui client, toate voucher-ele care au fost folosite de acel client să fie și ele șterse din baza de date (ștergere în cascadă) sau valoarea câmpului id_client pentru acele voucher-e să fie setată la NUL, ceea ce va înseamnă că acele voucher-e nu au fost folosite de niciun client.

Programe de validare si de actiune

În realizarea modelului conceptual al unei baze de date se ține cont de modul în care funcționează afacerea modelată, datele care trebuie să fie memorate, relațiile dintre acestea etc. Modul de utilizare a diferitelor date, modul în care acestea sunt relaționate pot diferi de la o afacere la alta.

Regulile afacerii unei organizații se referă în esență la procesele și fluxurile tuturor datelor și activităților zilnice din cadrul organizației. Cum funcționează organizația? Care sunt activitățile sale?

Regulile afacerii acoperă următoarele aspecte ale unei organizații:

 Orice tip de politici organizaționale de orice tip și de la orice nivel al organizației.

 Orice tip de formule de calcule (ca de exemplu modul de calcul al ratelor pentru diverse împrumuturi, modul de calcul al salariilor etc)

 Orice tip de reguli impuse de lege sau reguli interne ale organizației.

Regulile simple ale afacerii pot fi implementate în modelul bazei de date prin intermediul relațiilor dintre entități. Acest tip de reguli se numesc reguli structurale.

Alte reguli ale afacerii pot fi implementate folosind regulile de integritate despre care am discutat în paragraful anterior. Există totuși reguli pentru implementarea cărora va trebui să scriem programe speciale folosind limbaje specializate specifice SGBD-ului utilizat. Acest tip de reguli se numesc numite reguli procedurale. Acest tip de programe se vor scrie folosind limbajul PL/SQL (Procedural Language/Structuded Query Languge) și se numesc declanșatoare (triggere).

Există două tipuri de declanșatoare:

– declanșatoare de aplicație care se execută când apar anumite evenimente la nivelul anumitor evenimente;

– declanșatoare ale bazei de date care sunt lansate în execuție când apar diverse evenimente asupra datelor (de exemplu la executarea unor comenzi ca INSERT, UPDATE, DELETE) sau la apariția unor evenimente system (logarea la baza de date sau delogarea).

Orice declanșator poate avea rol de validare a unei operații, poate realiza diferite operații suplimentare, ca de exemplu diferite calcule, caz în care vom spune că e vorba de un declanșator de acțiune.

Spre exemplu, dacă un număr de telefon este definit că făcând parte din tabela MSISDN_PREPAY, el nu se poate să fie definit și în tabela MSISDN_POSTPAY. Motivul este foarte simplu, un număr de telefon nu poate fi utilizat simultan și că prepay și că postpay. Prin urmare apare necesitatea unicității unui atribut peste două entități din bază de date.

Această problemă se poate rezolvă folosind subtipuri, mapând cele două entități într-una singură sau se poate rezolva utilizând triggere în programe declanșator de acțiune.

Definiție unuia dintre trigger-e este :

DROP TRIGGER IF EXISTS `unique_msisdn_postpay`;

DELIMITER //

CREATE TRIGGER `unique_msisdn_postpay` BEFORE INSERT ON `msisdn_postpay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_prepay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

Operatii specific prelucrarii bazelor de date

Orice sistem de gestiune a bazelor de date (SGBD) trebuie să asigure următoarele funcții:

definirea structurii bazei de date

încărcarea datelor în baza de date (adăugarea de noi înregistrări la baza de date)

accesul la date pentru:

o interogare (afișarea datelor, sortarea lor, calcule statistice etc.)

o ștergere

o modificare

întreținerea bazei de date:

o refacerea bazei de date prin existența unor copii de siguranță

o repararea în caz de incident

o colectarea și refolosirea spațiilor goale

posibilitatea de reorganizare a bazei de date prin:

o restructurarea datelor

o modificarea accesului la date

securitatea datelor.

O parte din aceste operații pot fi realizate cu ajutorul limbajului SQL, altele cu ajutorul unor programe specializate, care sunt puse la dispoziția administratorului bazei de date de către sistemul de gestiune al bazelor de date.

WAMPSERVER

WampServer este un pachet ce conține Apache, MySQL, PHP și phpmyAdmin. Se instalează și configurează în aproximativ 1 minut și este foarte ușor de utilizat. De asemenea, există o bară de instrumente foarte la îndemână și folositoare. WampServer se folosește în general pentru a dezvolta site-uri web dinamice.

Pentru a începe să dezvoltăm site-uri în PHP avem nevoie de un server web, astfel că o să folosim WAMP 2.4. Această versiune are în dotare următoarele componente: Apache 2.4.4, Php 5.4.16, Mysql 5.6.12, PhpMyadmin 4.0.4. În momentul de față o să ne folosim doar de Apache și PHP, urmând să ajungem la MySQL și phpmyadmin.

După ce descărcăm programul începem instalarea acestuia conform indicațiilor de mai jos:

Pasul 1: Rulăm fișierul WampServer2.4-x86.exe

Pasul 2: Bifăm opțiunea “I accept the agreement” și apăsăm “Next”

Pasul 3: Alegem destinatia pentru instalarea serverului. Eu o sa lucrez cu destinatia default (“c:/wamp“) astfel ca va sfatuiesc sa nu o schimbati. Apasam “Next”

Pasul 4: În functie de preferinte optam pentru shortcut-uri, dupa care apasam “Next”

Pasul 5: Apăsam butonul “Instal”

Pasul 6: În acest moment serverul se instalează, configurând preferințele fiecărui utilizator. În funcție de performanțele fiecărui computer, această instalarea durează între 1 și 5 minute

Pasul 7: Nu o să folosim SMTP Server, drept urmare nu facem niciun fel de modificare în cadrul acestui pas, trecem mai departe apasând butonul “Next”

Pasul 8: Suntem înstiințați că serverul a fost instalat cu succes. Bifăm opțiunea: “Launch WampServer 2 now” și apăsam “Finish”

În acest moment serverul WAMP s-a instalat, astfel că ne ramâne doar să verificăm dacă această rulează corespunzător. Pentru a face această verificarea, deschidem un browser web și tastăm următoarea adresă: “http://localhost/” În urma acestui pas, trebuie să obținem o pagină asemănătoare celei din imaginea următoare:

Acesta a fost procesul de instalare a serverului WAMP.

Organizarea fișierelor în cadrul serverului WAMP
Serverul WAMP a fost instalat în “c:/wamp/”, astfel că se va accesa acel folder și astfel se va găsi structura standard pe care aceasta o crează încă de la instalare. În cadrul acesteia se găsește un folder numit “www” – reprezentând spațiul de lucru, deoarece serverul WAMP îl interpretează ca fiind principalul folder cu informații. Dacă intrăm în “c:/wamp/www” o să găsim un fișier numit “index.php” – acesta este fișierul pe care serverul îl accesează când se apeleaza dintr-un browser web adresa “http://localhost”. În cazul în care ștergem sau înlocuim fișierul “index.php” pierdem legăturile rapide pe care serverul le oferă.

Accesarea fișierelor
Pentru a testa interpretarea unui fișier în cadrul serverului, o să deschidem un browser web și o să apelăm “http://localhost/index.php“. În urma acestei apelări, se ajunge pe pagina de start a serverului, pagină accesata apelând “http://localhost“. Am dat acest exemplu, pentru a vă exemplifica faptul că serverul interpretează fișierele ce poartă numele de “index” chiar dacă nu îi specificăm acest lucru.

Proiectarea fizica a bazei de date

Pentru a crea o bază de date, un utilizator poate folosi instrucțiunea CREATE DATABASE, dar numai când a primit permisiuni în acest sens. Este necesară creerea unei baze de date, pentru ca mai apoi în această structură să pot fi create tabele. Este o formă simplistă, însă se pot utilza parametrii pentru a specifica spațiul alocat pe disc.

Trebuie evitat introducerea informațiilor dublate în baza de date iar pentru realizarea și exploatarea aplicației este necesar alegerea celui mai adecvat SGBD.

Pentru creearea bazei de date s-a executat urmatoarea comanda:

CREATE DATABASE IF NOT EXISTS `licenta`;

Pentru a putea crea un tabel sau a lucra cu alte comenzi intr-o baza de date, trebuie accesata baza de date existenta, acest lucru facandu-se folosind comanda:

USE nume_db;

Unde "nume_db" este numele bazei de date. Cu aceeasi comanda "USE nume_db" se schimba si baza de date in care vrem sa lucram.

Pentru utilizarea bazei de date s-a folosit urmatoarea comanda:

USE `licenta`;

Utilizatorii si schemele bazelor de date

Fiecare bază de date are o listă de nume de utilizatori. Pentru a accesa baza de date un utilizator trebuie să folosească o aplicație și să se conecteze cu un nume potrivit. Fiecărui nume de utilizator îi este asociată o parolă. Orice utilizator are un domeniu de securitate care determină privilegiile și rolurile, cota de spațiu pe disc alocat și limitele de resurse ce le poate utiliza (timp CPU etc).

Privilegiile

Privilegiul este dreptul unui utilizator de a executa anumite instrucțiuni SQL. Privilegiile pot fi:

privilegii de sistem – permit utilizatorilor să execute o gamă largă de instrucțiuni SQL, ce pot modifica datele sau structura bazei de date. Aceste privilegii se atribuie de obicei numai administratorilor bazei de date.

privilegii de obiecte – permit utilizatorilor să execute anumite instrucțiuni SQL numai în cadrul schemei sale, și nu asupra întregii baze de date.

Acordarea privilegiilor reprezintă modalitatea prin care acestea pot fi atribuite utilizatorilor. Există două căi de acordare explicit (privilegiile se atribuie în mod direct utilizatorilor) și implicit (prin atribuirea acestora unor roluri, care la rândul lor sunt acordate utilizatorilor).

Rolurile

Rolurile sunt grupe de privilegii, care se atribuie utilizatorilor sau altor roluri. Rolurile permit:

Reducerea activităților de atribuire a privilegiilor. Administratorul bazei de date în loc să atribuie fiecare privilegiu tuturor utilizatorilor va atribui aceste privilegii unui rol, care apoi va fi disponibil utilizatorilor;

Manipularea dinamică a privilegiilor. Dacă se modifică un privilegiu de grup, acesta se va modifica în rolul grupului. Automat modificarea privilegiului se propagă la toți utilizatorii din grup;

Selectarea disponibilităților privilegiilor. Privilegiile pot fi grupate pe mai multe roluri, care la rândul lor pot fi activate sau dezactivate în mod selectiv;

Proiectarea unor aplicații inteligente. Se pot activa sau dezactiva anumite roluri funcție de utilizatorii care încearcă să utilizeze aplicația.

Un rol poate fi creat cu parolă pentru a preveni accesul neautorizat la o aplicație. Această tehnică permite utilizarea parolei la momentul pornirii aplicației, apoi utilizatorii pot folosi aplicația fără să mai cunoască parola.

Pentru acordarea unui drept unui anumit utilizator Gabriel se va folosi comanda GRANT. De exemplu, pentru a se conecta la baza de date, un utilizator trebuie să aibă permisiunea de a crea o sesiune. Acest drept se alocă de către un utilizator privilegiat (utilizatorul system de exemplu) prin comanda

GRANT CREATE SESSION TO Gabriel

Acum utilizatorul Gabriel se poate conecta la baza de date.

Revocarea unui drept unui anumit utilizator se face folosind comanda REVOKE ca în exemplul următor:

REVOKE CREATE SESSION FROM Gabriel

Drepturile de sistem

Un drept de system permite unui utilizator să efectueze anumite operații asupra bazei de date precumexecutarea comenzilor DDL. Cele mai uzuale drepturi system sunt prezentate în tabelul următor.

Tabelul II.10.1. Privilegii sistem

Crearea tabelelor

După etapa de modelare a bazelor de date, primul pas în realizarea unei aplicații de baze de date constă în crearea obiectelor ce compun baza de date: tabele, indexi, vederi, sinonime etc.

Crearea tabelelor, presupune stabilirea numelor tabelelor și a coloanelor ce le compun, stabilirea tipurilor de date pe care le au coloanele tabelei, dar și declararea restricțiilor (constrângerilor) care asigură integritatea și coerența informațiilor din baza de date.

Un tabel se mai numește și relație. Acesta conține toate datele necesare despre ceva din lumea reală, în cazul nostru despre abonați post-pay și cei pre-pay. Un singur rând din tabel reprezintă toate datele necesare pentru un abonat. Fiecare rând este identificat de o cheie primară pentru a nu avea duplicate în tabel. Ordinea rândurilor nu are importanță într-o relație. O coloană este atributul unei entități (rând) din baza de date. Numărul abonatului identifică un abonat unic baza de date, așadar acesta reprezintă cheia primară a tabelului. O cheie primară trebuie să conțină o valoare unică. Nu toate coloanele reprezintă chei primare, pot exista și atribute, cum ar fi numărul de telefon fără ca acesta să fie cheie primară, deși și acesta este unic.

Un câmp nu are neapărat o valoare, se află la intersecția dintre o coloană și un rând, dar dacă are valori atunci va avea una singură.

Tabelele stochează date, ele pot fi create și modificate la orice moment de timp. Nu trebuie specificată dimensiunea unui tabel în avans.

Numele tabelelor și al coloanelor ce îl alcătuiesc are dimensiunea maximă de 30 de caractere, pot conține litere (chiar și majuscule), cifre, și dintre caracterele speciale _, $ și #. Titlul începe obligatoriu cu o literă, dar acesta nu este case sensitive.

Pentru crearea unei tabele se folosește comanda CREATE TABLE. Cea mai simplă formă a acestei comenzi, în care pentru moment nu se definesc valori implicite pentru coloane și nu definim nici o restricție este:

CREATE TABLE numetabel

( coloana1 tip1,

coloana2 tip2,

coloanan tipn );

unde – numetabel este numele atribuit tabelului nou creat. Acest nume trebuie să respecte restricțiile privind definirea numelor despre care a discutat în capitolul II.1.

– coloana1, coloana2, …, coloanan sunt numele coloanelor din tabela nou creată

– tip1, tip2, …, tipn reprezintă tipul datelor ce vor fi reținute în coloanele tabelei nou create și dimensiunea (dacă este cazul). Principalele tipurile de date existente în MySQL au fost prezentate în capitolul 8. Pe lângă numele tipului respectiv se precizează în paranteză lungimea tipului, respectiv numărul de caractere pentru un șir de caractere, sau numărul total de cifre și numărul de cifre de după virgulă pentru valorile numerice.

Pentru a insera fizic aceste tabele in baza de date se vor executa urmatoarele comenzi SQL:

CREATE TABLE IF NOT EXISTS `angajat` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`prenume` varchar(30) NOT NUL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

CREATE TABLE IF NOT EXISTS `client` (

`id` int(8) unsigned NOT NUL AUTO_INCREMENT,

`cnp` varchar(13) NOT NUL,

`nume` varchar(25) NOT NUL,

`prenume` varchar(30) NOT NUL,

`adresa` varchar(100) NOT NUL,

`data_inregistrarii` date NOT NUL,

`mail` varchar(50) DEFAULT NUL,

`id_angajat` int(10) unsigned NOT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `cnp` (`cnp`),

KEY `id_angajat` (`id_angajat`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

CREATE TABLE IF NOT EXISTS `msisdn_postpay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nr_tel` varchar(10) NOT NUL,

`restant` enum('DA','NU') NOT NUL DEFAULT 'NU',

`roaming` enum('DA','NU') NOT NUL DEFAULT 'NU',

`data_facturare` enum('1st','15th','25th') NOT NUL,

`suma_platita` int(10) unsigned NOT NUL DEFAULT '0',

`id_client` int(10) unsigned DEFAULT NUL,

`id_serviciu_postpay` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `nr_tel` (`nr_tel`),

KEY `id_client` (`id_client`),

KEY `id_serviciu_postpay` (`id_serviciu_postpay`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS `serviciu_postpay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`min_nat` int(7) NOT NUL,

`min_retea` int(7) NOT NUL,

`sms_nat` int(11) NOT NUL,

`sms_retea` int(11) NOT NUL,

`nr_mb` int(11) NOT NUL,

`pret` int(11) NOT NUL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

CREATE TABLE IF NOT EXISTS `msisdn_prepay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nr_tel` varchar(10) NOT NUL,

`credit` int(11) NOT NUL,

`roaming` enum('DA','NU') NOT NUL DEFAULT 'NU',

`id_client` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `nr_tel` (`nr_tel`),

KEY `id_client` (`id_client`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS `serviciu_prepay` (

`id` int(11) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`min_nat` int(7) NOT NUL,

`min_retea` int(7) NOT NUL,

`sms_nat` int(11) NOT NUL,

`sms_retea` int(11) NOT NUL,

`nr_mb` int(11) NOT NUL,

`pret` int(11) NOT NUL COMMENT 'Pretul este exprimat in Euro',

`valabilitate` int(11) NOT NUL DEFAULT '30',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS `act_opt_prepay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`data_activare` date NOT NUL,

`id_msisdn_prepay` int(10) unsigned NOT NUL,

`id_serviciu_prepay` int(11) unsigned NOT NUL,

PRIMARY KEY (`id`),

KEY `id_msisdn_prepay` (`id_msisdn_prepay`),

KEY `id_serviciu_prepay` (`id_serviciu_prepay`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

In imaginea de mai jos se vede rezultatul executiei comenzilor de mai sus, si anume, se observa faptul ca tabelele au fost create.

Adaugarea constrangerilor

Deoarece structura bazelor de date trebuie să modeleze realitatea, datele conținute de acestea trebuie să se încadreze în anumite mulțimi de valori. Aceste constrângeri sunt definite ca niște reguli la proiectarea bazei de date și trebuie respectate întotdeauna.

Se pot diferenția două tipuri de constrângeri din punctul de vedere al locului unde sunt definite: intra-relație și inter-relație. Cele intra-relație se referă la o singură relație (sau tabelă, în practică) și se împart în constrângeri de domeniu, constrângeri de tuplu etc. Cele inter-relație se refera la una sau mai multe tabele, fiind modelate prin cheile străine și asigurând asocierea corectă a relațiilor.

Constrângerile de domeniu sunt impuse valorilor atributelor pentru ca acestea să corespundă realității. Acestea afectează coloanele și din acest motiv, se mai numesc și constrângeri de coloană. Există constrângeri care se pot aplica pe orice tip de coloana (de exemplu, DEFAULT care setează valoarea implicită a atributelor relației sau NOT NUL care constrânge coloana sa aibă valori valide).

Constrangerile de tuplu (cheie primară și chei secundare) afectează tabela în sensul că aceasta nu trebuie să conțină rânduri duplicate. De asemenea, se pot impune constrangeri asupra combinatiilor de valori ale atributelor tuplurilor. Nu trebuie să existe tupluri distincte în care să existe aceleași combinații de valori ale anumitor atribute.

La crearea tabelei „CLIENT” s-au specificat constrângeri de domeniu prin specificarea „not nul” dupa declararea mai multor coloane. NUL este o valoare generala, asociata tuturor tipurilor de date dintr-o baza de date care modeleaza lipsa unei valori a campului respectiv.

Mai pot fi impuse constrângeri care să asigure că modelarea realității este cât mai fidelă. De exemplu, pentru tabela „CLIENT”, se observa ca exista un camp care modeleaza campul „cnp”. Se poate impune o constrangere de tip „check” care sa se asigure ca orice valoare introdusa pentru coloana „cnp” este formata din strict 13 caractere.

S-a considerat necesara aceasta constrangere datorita faptului ca un abonat poate fi identificat prin codul sau, deci acesta trebuie sa fie unic pentru a nu identifica mai multi abonati prin acelasi cod. El reprezinta codul numeric personal al fiecărei persoane.

Chei candidate, primare si straine

Trebuie să existe posibilitatea de identificare unică a unui tuplu dintr-o relație, prin valorile atributelor sale. Astfel că s-au definit următoarele chei relaționale:

O supercheie este o submulțime de atribute ale unei relații care are proprietatea că orice combinație a valorilor atributelor este unică în relația respectivă. Cu alte cuvinte, o combinație a valorilor atributelor respective identifică în mod unic un tuplu.

Pentru tabela „CLIENT”, un exemplu de supercheie ar fi combinația: nume, cod sau chiar numărul de telefon deoarece aceastea ar identifica în mod unic un abonat. Pentru tabela „MSISDN_PREPAY” nu există o astfel de cheie.

O cheie candidata este o supercheie ireductibila (nu există o submulțime a atributelor supercheii care să aibă proprietatea că identifică în mod unic un tuplu). Această cheie poate fi formată din unul sau mai multe atribute și condiția de unicitate reprezintă o constrângere de integritate impusă asupra modelului respectiv.

Cheile candidate din tabela „CLIENT” sunt id-ul, codul și numărul de telefon deoarece acestea identifica în mod unic un abonat. În cazul în care se identifica mai multe chei candidate, una dintre acestea este desemnată cheie primară, celelalte fiind chei secundare (unice). Cheii primare i se atribuie rolul de a identifica in mod unic un tuplu si i se impune ca niciunul dintre atributele sale sa nu accepte valori NUL. Aceasta cheie se poate alege din toate cheile candidate, dar se prefera cea cu cele mai putine atribute, din ratiuni de eficienta. Cheile primare pot fi naturale (formate din unul sau mai multe atribute existente in relatie) sau artificiale (construite special pentru identificarea unica a tuplurilor; de obicei, cheile artificiale sunt formate dintr-un singur atribut al relatiei).

În tabela „CLIENT”, se observa că atributul „cnp” poate fi o cheie primara naturala deoarece atributul exista deja in relatie și a fost deja constrâns sa fie unic. Pe de alta parte, atributul id poate fi o cheie primară artificială deoarece acesta a fost creat pentru a usura introducerea datelor în tabel. Se va alege ca cheie primară id-ul abonatului deoarece acesta este mai scurt și căutarea în tabel poate dura mai puțin. De asemenea se va constrânge ca id-ul să se incrementeze singur, astfel încat operatorul să nu mai fie nevoit să îl aduge de fiecare data când introduce date în tabelă. În cazul in care codul acesta trebuie introdus de fiecare data din cauza lungimii lui se pot strecura greseli foarte ușor.

Este eficient ca utilizatorul să nu fie nevoit să știe de existența câmpului id și mai ales, să nu fie nevoit să stie ce valoare trebuie să specifice în instrucțiunile de tip insert. De aceea, se poate implementa un sistem în care valorile cheii primare, în acest caz este vorba despre valorile câmpului id, să se incrementeze automat.

Pentru aceasta, este necesar sa se defineasca o secventa de numere pentru care se specifica valoarea de inceput, incrementul și eventual, valoarea maximă.

Pentru tabelul „client” s-a definit urmatoarea secvență:

Pentru toate celelalte tabele care folosesc chei artificiale ce necesită autoincrementarea, se va defini câte o astfel de secvență ce ulterior va fi implementată cu ajutorul unui declanșator de program (trigger).

După definirea secvenței, se creează un trigger pe tabela înainte de inserare. Acesta selectează din secvența creată urmatoarea valoare pe care o va folosi pentru valoarea cheii primare a noului tuplu introdus prin insert. Astfel, înainte de inserarea oricărei linii noi în tabela, se execută triggerul. Acesta selectează urmatoarea valoare a secvenței și o folosește pentru completarea câmpului id a tuplului care se introduce.

O secvență este un obiect al bazei de date care memorează o secvență de numere. Acest lucru este util atunci cand se dorește definirea unei chei primare și setarea proprietății de autoincrement a coloanei respective.

Un trigger este o procedură stocată speciala în sensul că este declansată (executată) automat în urma unei alte acțiuni ce a fost facută asupra tabelei (de exemplu, dupa inserarea unui tuplu, inainte de inserarea unui tuplu sau inainte/dupa executarea unui update, se poate dori executarea automata a unei instructiuni suplimentare).

În urma definirii secvenței și a trigger-ului, nu mai este necesar să se specifice valori pentru id atunci când se face o operație de insert în tabelă respectivă.

Pentru tabela „CLIENT” s-a creat următorul trigger:

De asemenea, este imperios necesar să se creeze câte un astfel de trigger pentru fiecare secvență corespunzătoare fiecărei tabele. Se observă apariția tabelei „DUAL”. Deși este considerată că fiind specifică „Oracle”, ea apare și în MySQL. Are exact aceeași funcție că și în cazul „Oracle” și anume de a facilita anumite operații. Aceasta tabela este una specială, care conține o singură coloană numită ”DUMMY” și o singură linie. Tabela DUAL se folosește atunci când realizăm calcule, sau evaluăm expresii care nu derivă din nici o tabelă anume.

Fie de exemplu comanda:

SELECT (5*7-3)/2 FROM DUAL;

Expresia evaluată în această comandă nu are în componență nici o coloană a vreunei tabele, motiv pentru care este nevoie să apelăm la tabela DUAL. Putem privi tabela DUAL ca pe o variabilă în care memorăm rezultatele calculelor noastre.

Realizarea vederilor

O vedere este deseori numită și o tabelă virtuală. Vederile sunt create utilizând instrucțiunea CREATE VIEW.

Se pot folosi vederi sau tabele virtuale pentru a încapsula query-uri complexe. După crearea unei vederi asupra unui set de date, acea vedere poate fi tratată că orice altă tabela. Însă, sunt aplicate restricții speciale în ceea ce privește modificarea datelor din acele vederi. Când datele dintr-o tabela se modifică, ceea ce se obține interogând o vedere de asemenea se modifică. Vederile nu ocupă spațiu în memoria fizică, astfel diferentiindu-se de tabele.

Sintaxa pentru instrucțiunea CREATE VIEW este:

CREATE VIEW <numele_vederii> [(coloana1, coloana2…)] AS

SELECT <numele_tabelei numele_coloanei>

FROM <numele_tabelei>

Deși sintaxa poate părea dificil de înțeles, ea va fi exemplificată în numeroase rânduri în cele ce urmează tocmai pentru a ilustra diferitele situații de utilizare dar și avantajele vederilor. Setul de instrucțiuni prezentate mai sus au că efect crearea unei vederi al cărui nume va fi specificat în câmpul „numele_vederii” și care cuprinde mai multe coloane al căror nume poate fi de asemenea specificat. O instrucțiune SELECT va determină câmpurile și tipurile de date.

Se pot crea chiar și noi vederi folosind vederi deja existente. Totuși trebuie luat aminte faptul că atunci când se crează vederi ale vederilor, deși acest lucru este acceptabil, el complică foarte mult mentenanța întregului sistem. Să presupunem că avem o vedere de nivelul trei provenită dintr-o tabela (vederea unei vederi a unei vederi a unei tabele). Dacă prima vedere ar dispărea că urmare a unui DROP, celelalte două vederi ar continuă să existe dar ar fi unitule deoarece și-au obținut parte din informațiile necesare din prima vedere. Este așadar de ținut minte faptul că o data ce o vedere a fost creață ea se comportă că și o tabela virtuală. Utilizatorii pot crea vederi pentru interogarea diferitelor date. După crearea unei vederi se pot modifică, insera sau șterge date folosind instrucțiunile UPDATE, INSERT și DELETE.

Deoarece ceea ce se vede folosind o vedere poate fi un set dintr-un grup de tabele, modificarea datelor din tabelele aferente nu este întotdeauna simplă. Urmatoarea listă este una a celor mai comune restricții ce vor fi întâmpinate ăn lucrul cu vederi:

1) Nu se poate folosi DELETE pe mai multe vederi

2) Nu se poate folosi INSERT decât în situația în care toate coloanele NOT NUL folosite în tabelele asociate sunt incluse în vedere. Această restricție se aplică deoarece procesorul SQL nu știe ce valoare să însereze în coloanele NOT NUL.

3) Dacă se inserează sau se actualizarea înregistrări folosint un join view, toate înregistrările ce sunt actualizate trebuie să aparțină aceleiași tabele fizice

4) Dacă se folosește clauza DISTINCT pentru a creă o vedere, nu se poate actualiza sau însera în acea vedere

5) Nu se poate actualiza o coloană virtuală (coloană care este rezultatul unei expresii sau unei funcții)

Anexe:

Anexa1:

– phpMyAdmin SQL Dump

– version 4.0.4

– http://www.phpmyadmin.net

– Host: localhost

– Generation Time: Jun 24, 2014 at 10:32 PM

– Server version: 5.6.12-log

– PHP Version: 5.4.16

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";

SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

/*!40101 SET @OLD_COLATION_CONNECTION=@@COLATION_CONNECTION */;

/*!40101 SET NAMES utf8 */;

– Database: `licenta`

CREATE DATABASE IF NOT EXISTS `licenta` DEFAULT CHARACTER SET latin1 COLATE latin1_swedish_ci;

USE `licenta`;

– –––––––––––––––––––

– Table structure for table `act_opt_prepay`

CREATE TABLE IF NOT EXISTS `act_opt_prepay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`data_activare` date NOT NUL,

`id_msisdn_prepay` int(10) unsigned NOT NUL,

`id_serviciu_prepay` int(11) unsigned NOT NUL,

PRIMARY KEY (`id`),

KEY `id_msisdn_prepay` (`id_msisdn_prepay`),

KEY `id_serviciu_prepay` (`id_serviciu_prepay`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

– Dumping data for table `act_opt_prepay`

INSERT INTO `act_opt_prepay` (`id`, `data_activare`, `id_msisdn_prepay`, `id_serviciu_prepay`) VALUES

(1, '2014-06-18', 1, 2);

– –––––––––––––––––––

– Table structure for table `angajat`

CREATE TABLE IF NOT EXISTS `angajat` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`prenume` varchar(30) NOT NUL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

– Dumping data for table `angajat`

INSERT INTO `angajat` (`id`, `nume`, `prenume`) VALUES

(1, 'Neamtu', 'Codrina'),

(2, 'Popescu', 'Daniel'),

(3, 'Ionescu', 'Paul');

– –––––––––––––––––––

– Table structure for table `client`

CREATE TABLE IF NOT EXISTS `client` (

`id` int(8) unsigned NOT NUL AUTO_INCREMENT,

`cnp` varchar(13) NOT NUL,

`nume` varchar(25) NOT NUL,

`prenume` varchar(30) NOT NUL,

`adresa` varchar(100) NOT NUL,

`data_inregistrarii` date NOT NUL,

`mail` varchar(50) DEFAULT NUL,

`id_angajat` int(10) unsigned NOT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `cnp` (`cnp`),

KEY `id_angajat` (`id_angajat`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `client`

INSERT INTO `client` (`id`, `cnp`, `nume`, `prenume`, `adresa`, `data_inregistrarii`, `mail`, `id_angajat`) VALUES

(1, '[anonimizat]', 'Toma', 'Sorin', 'Bucuresti', '2014-06-10', '[anonimizat]', 1),

(2, '[anonimizat]', 'Anastase', 'Cristina-Laura', 'Bucuresti', '2014-04-15', '[anonimizat]', 2);

– –––––––––––––––––––

– Table structure for table `msisdn_postpay`

CREATE TABLE IF NOT EXISTS `msisdn_postpay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nr_tel` varchar(10) NOT NUL,

`restant` enum('DA','NU') NOT NUL DEFAULT 'NU',

`roaming` enum('DA','NU') NOT NUL DEFAULT 'NU',

`data_facturare` enum('1st','15th','25th') NOT NUL,

`suma_platita` int(10) unsigned NOT NUL DEFAULT '0' COMMENT 'Suma platita de client',

`id_client` int(10) unsigned DEFAULT NUL,

`id_serviciu_postpay` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `nr_tel` (`nr_tel`),

KEY `id_client` (`id_client`),

KEY `id_serviciu_postpay` (`id_serviciu_postpay`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

– Dumping data for table `msisdn_postpay`

INSERT INTO `msisdn_postpay` (`id`, `nr_tel`, `restant`, `roaming`, `data_facturare`, `suma_platita`, `id_client`, `id_serviciu_postpay`) VALUES

(1, '0720123456', 'NU', 'NU', '1st', 0, 1, 2);

– Triggers `msisdn_postpay`

DROP TRIGGER IF EXISTS `unique_msisdn_postpay`;

DELIMITER //

CREATE TRIGGER `unique_msisdn_postpay` BEFORE INSERT ON `msisdn_postpay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_prepay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

DROP TRIGGER IF EXISTS `unique_update_msisdn_postpay`;

DELIMITER //

CREATE TRIGGER `unique_update_msisdn_postpay` BEFORE UPDATE ON `msisdn_postpay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_prepay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

– –––––––––––––––––––

– Table structure for table `msisdn_prepay`

CREATE TABLE IF NOT EXISTS `msisdn_prepay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nr_tel` varchar(10) NOT NUL,

`credit` int(11) NOT NUL,

`roaming` enum('DA','NU') NOT NUL DEFAULT 'NU',

`id_client` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `nr_tel` (`nr_tel`),

KEY `id_client` (`id_client`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `msisdn_prepay`

INSERT INTO `msisdn_prepay` (`id`, `nr_tel`, `credit`, `roaming`, `id_client`) VALUES

(1, '0734123456', 5, 'NU', 2),

(2, '0765341231', 10, 'DA', 1);

– Triggers `msisdn_prepay`

DROP TRIGGER IF EXISTS `unique_msisdn_prepay`;

DELIMITER //

CREATE TRIGGER `unique_msisdn_prepay` BEFORE INSERT ON `msisdn_prepay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_postpay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

DROP TRIGGER IF EXISTS `unique_update_msisdn_prepay`;

DELIMITER //

CREATE TRIGGER `unique_update_msisdn_prepay` BEFORE UPDATE ON `msisdn_prepay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_postpay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

– –––––––––––––––––––

– Table structure for table `serviciu_postpay`

CREATE TABLE IF NOT EXISTS `serviciu_postpay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`min_nat` int(7) NOT NUL,

`min_retea` int(7) NOT NUL,

`sms_nat` int(11) NOT NUL,

`sms_retea` int(11) NOT NUL,

`nr_mb` int(11) NOT NUL,

`pret` int(11) NOT NUL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `serviciu_postpay`

INSERT INTO `serviciu_postpay` (`id`, `nume`, `min_nat`, `min_retea`, `sms_nat`, `sms_retea`, `nr_mb`, `pret`) VALUES

(1, 'Alfa', 1000, 1000, 500, 500, 1024, 6),

(2, 'Beta', 2000, 2000, 1000, 1000, 2048, 8);

– –––––––––––––––––––

– Table structure for table `serviciu_prepay`

CREATE TABLE IF NOT EXISTS `serviciu_prepay` (

`id` int(11) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`min_nat` int(7) NOT NUL,

`min_retea` int(7) NOT NUL,

`sms_nat` int(11) NOT NUL,

`sms_retea` int(11) NOT NUL,

`nr_mb` int(11) NOT NUL,

`pret` int(11) NOT NUL COMMENT 'Pretul este exprimat in Euro',

`valabilitate` int(11) NOT NUL DEFAULT '30' COMMENT 'Numarul de zile pentru care optiunea este valabila',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `serviciu_prepay`

INSERT INTO `serviciu_prepay` (`id`, `nume`, `min_nat`, `min_retea`, `sms_nat`, `sms_retea`, `nr_mb`, `pret`, `valabilitate`) VALUES

(1, '2500m2500s', 250, 2500, 500, 2500, 1024, 5, 30),

(2, '100min100sms', 100, 1000, 100, 1000, 1024, 4, 30);

– –––––––––––––––––––

– Table structure for table `voucher`

CREATE TABLE IF NOT EXISTS `voucher` (

`id` int(11) unsigned NOT NUL AUTO_INCREMENT,

`cod` varchar(10) NOT NUL,

`valoare` int(11) NOT NUL COMMENT 'Suma de bani exprimata in Euro',

`data_folosire` date DEFAULT NUL,

`id_client` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

KEY `id_client` (`id_client`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `voucher`

INSERT INTO `voucher` (`id`, `cod`, `valoare`, `data_folosire`, `id_client`) VALUES

(1, '123456', 5, NUL, NUL),

(2, '102938', 5, NUL, NUL);

– Constraints for dumped tables

– Constraints for table `act_opt_prepay`

ALTER TABLE `act_opt_prepay`

ADD CONSTRAINT `msisdn_prepay_act_fk` FOREIGN KEY (`id_msisdn_prepay`) REFERENCES `msisdn_prepay` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,

ADD CONSTRAINT `serviciu_prepay_act_fk` FOREIGN KEY (`id_serviciu_prepay`) REFERENCES `serviciu_prepay` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

– Constraints for table `client`

ALTER TABLE `client`

ADD CONSTRAINT `angajat_fk` FOREIGN KEY (`id_angajat`) REFERENCES `angajat` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

– Constraints for table `msisdn_postpay`

ALTER TABLE `msisdn_postpay`

ADD CONSTRAINT `client_fk` FOREIGN KEY (`id_client`) REFERENCES `client` (`id`) ON DELETE SET NUL ON UPDATE NO ACTION,

ADD CONSTRAINT `serviciu_postpay_fk` FOREIGN KEY (`id_serviciu_postpay`) REFERENCES `serviciu_postpay` (`id`) ON DELETE SET NUL ON UPDATE NO ACTION;

– Constraints for table `msisdn_prepay`

ALTER TABLE `msisdn_prepay`

ADD CONSTRAINT `client_prepay_fk` FOREIGN KEY (`id_client`) REFERENCES `client` (`id`) ON DELETE SET NUL ON UPDATE NO ACTION;

– Constraints for table `voucher`

ALTER TABLE `voucher`

ADD CONSTRAINT `client_voucher_fk` FOREIGN KEY (`id_client`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;

/*!40101 SET COLATION_CONNECTION=@OLD_COLATION_CONNECTION */;

Bibliografie

[1] Weling, L., Thomson, L., „Dezvoltarea aplicatiilor Web cu PHP si MySQL”, Editura Teora,2005

[2] Galațchi, D., Note de curs: „Inginerie software pentru comunicații”

[3] http://www.datatables.net/ accesat la data 25.06.2014

[4] http://dev.mysql.com/doc/ accesat la data 17.05.2014

[5] http://www.php.net/ accesat la data 23.04.2014

[6] http://www.cssbuttongenerator.com/ accesat la data 23.05.2014

Bibliografie

[1] Weling, L., Thomson, L., „Dezvoltarea aplicatiilor Web cu PHP si MySQL”, Editura Teora,2005

[2] Galațchi, D., Note de curs: „Inginerie software pentru comunicații”

[3] http://www.datatables.net/ accesat la data 25.06.2014

[4] http://dev.mysql.com/doc/ accesat la data 17.05.2014

[5] http://www.php.net/ accesat la data 23.04.2014

[6] http://www.cssbuttongenerator.com/ accesat la data 23.05.2014

Anexe:

Anexa1:

– phpMyAdmin SQL Dump

– version 4.0.4

– http://www.phpmyadmin.net

– Host: localhost

– Generation Time: Jun 24, 2014 at 10:32 PM

– Server version: 5.6.12-log

– PHP Version: 5.4.16

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";

SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

/*!40101 SET @OLD_COLATION_CONNECTION=@@COLATION_CONNECTION */;

/*!40101 SET NAMES utf8 */;

– Database: `licenta`

CREATE DATABASE IF NOT EXISTS `licenta` DEFAULT CHARACTER SET latin1 COLATE latin1_swedish_ci;

USE `licenta`;

– –––––––––––––––––––

– Table structure for table `act_opt_prepay`

CREATE TABLE IF NOT EXISTS `act_opt_prepay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`data_activare` date NOT NUL,

`id_msisdn_prepay` int(10) unsigned NOT NUL,

`id_serviciu_prepay` int(11) unsigned NOT NUL,

PRIMARY KEY (`id`),

KEY `id_msisdn_prepay` (`id_msisdn_prepay`),

KEY `id_serviciu_prepay` (`id_serviciu_prepay`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

– Dumping data for table `act_opt_prepay`

INSERT INTO `act_opt_prepay` (`id`, `data_activare`, `id_msisdn_prepay`, `id_serviciu_prepay`) VALUES

(1, '2014-06-18', 1, 2);

– –––––––––––––––––––

– Table structure for table `angajat`

CREATE TABLE IF NOT EXISTS `angajat` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`prenume` varchar(30) NOT NUL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

– Dumping data for table `angajat`

INSERT INTO `angajat` (`id`, `nume`, `prenume`) VALUES

(1, 'Neamtu', 'Codrina'),

(2, 'Popescu', 'Daniel'),

(3, 'Ionescu', 'Paul');

– –––––––––––––––––––

– Table structure for table `client`

CREATE TABLE IF NOT EXISTS `client` (

`id` int(8) unsigned NOT NUL AUTO_INCREMENT,

`cnp` varchar(13) NOT NUL,

`nume` varchar(25) NOT NUL,

`prenume` varchar(30) NOT NUL,

`adresa` varchar(100) NOT NUL,

`data_inregistrarii` date NOT NUL,

`mail` varchar(50) DEFAULT NUL,

`id_angajat` int(10) unsigned NOT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `cnp` (`cnp`),

KEY `id_angajat` (`id_angajat`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `client`

INSERT INTO `client` (`id`, `cnp`, `nume`, `prenume`, `adresa`, `data_inregistrarii`, `mail`, `id_angajat`) VALUES

(1, '[anonimizat]', 'Toma', 'Sorin', 'Bucuresti', '2014-06-10', '[anonimizat]', 1),

(2, '[anonimizat]', 'Anastase', 'Cristina-Laura', 'Bucuresti', '2014-04-15', '[anonimizat]', 2);

– –––––––––––––––––––

– Table structure for table `msisdn_postpay`

CREATE TABLE IF NOT EXISTS `msisdn_postpay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nr_tel` varchar(10) NOT NUL,

`restant` enum('DA','NU') NOT NUL DEFAULT 'NU',

`roaming` enum('DA','NU') NOT NUL DEFAULT 'NU',

`data_facturare` enum('1st','15th','25th') NOT NUL,

`suma_platita` int(10) unsigned NOT NUL DEFAULT '0' COMMENT 'Suma platita de client',

`id_client` int(10) unsigned DEFAULT NUL,

`id_serviciu_postpay` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `nr_tel` (`nr_tel`),

KEY `id_client` (`id_client`),

KEY `id_serviciu_postpay` (`id_serviciu_postpay`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

– Dumping data for table `msisdn_postpay`

INSERT INTO `msisdn_postpay` (`id`, `nr_tel`, `restant`, `roaming`, `data_facturare`, `suma_platita`, `id_client`, `id_serviciu_postpay`) VALUES

(1, '0720123456', 'NU', 'NU', '1st', 0, 1, 2);

– Triggers `msisdn_postpay`

DROP TRIGGER IF EXISTS `unique_msisdn_postpay`;

DELIMITER //

CREATE TRIGGER `unique_msisdn_postpay` BEFORE INSERT ON `msisdn_postpay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_prepay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

DROP TRIGGER IF EXISTS `unique_update_msisdn_postpay`;

DELIMITER //

CREATE TRIGGER `unique_update_msisdn_postpay` BEFORE UPDATE ON `msisdn_postpay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_prepay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

– –––––––––––––––––––

– Table structure for table `msisdn_prepay`

CREATE TABLE IF NOT EXISTS `msisdn_prepay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nr_tel` varchar(10) NOT NUL,

`credit` int(11) NOT NUL,

`roaming` enum('DA','NU') NOT NUL DEFAULT 'NU',

`id_client` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

UNIQUE KEY `nr_tel` (`nr_tel`),

KEY `id_client` (`id_client`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `msisdn_prepay`

INSERT INTO `msisdn_prepay` (`id`, `nr_tel`, `credit`, `roaming`, `id_client`) VALUES

(1, '0734123456', 5, 'NU', 2),

(2, '0765341231', 10, 'DA', 1);

– Triggers `msisdn_prepay`

DROP TRIGGER IF EXISTS `unique_msisdn_prepay`;

DELIMITER //

CREATE TRIGGER `unique_msisdn_prepay` BEFORE INSERT ON `msisdn_prepay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_postpay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

DROP TRIGGER IF EXISTS `unique_update_msisdn_prepay`;

DELIMITER //

CREATE TRIGGER `unique_update_msisdn_prepay` BEFORE UPDATE ON `msisdn_prepay`

FOR EACH ROW BEGIN

DECLARE c INT;

SELECT COUNT(*) INTO c FROM msisdn_postpay WHERE nr_tel = NEW.nr_tel;

IF (c > 0) THEN

– abort insert, because foo.username should be NOT NUL

SET NEW.nr_tel = NUL;

END IF;

END

//

DELIMITER ;

– –––––––––––––––––––

– Table structure for table `serviciu_postpay`

CREATE TABLE IF NOT EXISTS `serviciu_postpay` (

`id` int(10) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`min_nat` int(7) NOT NUL,

`min_retea` int(7) NOT NUL,

`sms_nat` int(11) NOT NUL,

`sms_retea` int(11) NOT NUL,

`nr_mb` int(11) NOT NUL,

`pret` int(11) NOT NUL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `serviciu_postpay`

INSERT INTO `serviciu_postpay` (`id`, `nume`, `min_nat`, `min_retea`, `sms_nat`, `sms_retea`, `nr_mb`, `pret`) VALUES

(1, 'Alfa', 1000, 1000, 500, 500, 1024, 6),

(2, 'Beta', 2000, 2000, 1000, 1000, 2048, 8);

– –––––––––––––––––––

– Table structure for table `serviciu_prepay`

CREATE TABLE IF NOT EXISTS `serviciu_prepay` (

`id` int(11) unsigned NOT NUL AUTO_INCREMENT,

`nume` varchar(25) NOT NUL,

`min_nat` int(7) NOT NUL,

`min_retea` int(7) NOT NUL,

`sms_nat` int(11) NOT NUL,

`sms_retea` int(11) NOT NUL,

`nr_mb` int(11) NOT NUL,

`pret` int(11) NOT NUL COMMENT 'Pretul este exprimat in Euro',

`valabilitate` int(11) NOT NUL DEFAULT '30' COMMENT 'Numarul de zile pentru care optiunea este valabila',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `serviciu_prepay`

INSERT INTO `serviciu_prepay` (`id`, `nume`, `min_nat`, `min_retea`, `sms_nat`, `sms_retea`, `nr_mb`, `pret`, `valabilitate`) VALUES

(1, '2500m2500s', 250, 2500, 500, 2500, 1024, 5, 30),

(2, '100min100sms', 100, 1000, 100, 1000, 1024, 4, 30);

– –––––––––––––––––––

– Table structure for table `voucher`

CREATE TABLE IF NOT EXISTS `voucher` (

`id` int(11) unsigned NOT NUL AUTO_INCREMENT,

`cod` varchar(10) NOT NUL,

`valoare` int(11) NOT NUL COMMENT 'Suma de bani exprimata in Euro',

`data_folosire` date DEFAULT NUL,

`id_client` int(10) unsigned DEFAULT NUL,

PRIMARY KEY (`id`),

KEY `id_client` (`id_client`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

– Dumping data for table `voucher`

INSERT INTO `voucher` (`id`, `cod`, `valoare`, `data_folosire`, `id_client`) VALUES

(1, '123456', 5, NUL, NUL),

(2, '102938', 5, NUL, NUL);

– Constraints for dumped tables

– Constraints for table `act_opt_prepay`

ALTER TABLE `act_opt_prepay`

ADD CONSTRAINT `msisdn_prepay_act_fk` FOREIGN KEY (`id_msisdn_prepay`) REFERENCES `msisdn_prepay` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,

ADD CONSTRAINT `serviciu_prepay_act_fk` FOREIGN KEY (`id_serviciu_prepay`) REFERENCES `serviciu_prepay` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

– Constraints for table `client`

ALTER TABLE `client`

ADD CONSTRAINT `angajat_fk` FOREIGN KEY (`id_angajat`) REFERENCES `angajat` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

– Constraints for table `msisdn_postpay`

ALTER TABLE `msisdn_postpay`

ADD CONSTRAINT `client_fk` FOREIGN KEY (`id_client`) REFERENCES `client` (`id`) ON DELETE SET NUL ON UPDATE NO ACTION,

ADD CONSTRAINT `serviciu_postpay_fk` FOREIGN KEY (`id_serviciu_postpay`) REFERENCES `serviciu_postpay` (`id`) ON DELETE SET NUL ON UPDATE NO ACTION;

– Constraints for table `msisdn_prepay`

ALTER TABLE `msisdn_prepay`

ADD CONSTRAINT `client_prepay_fk` FOREIGN KEY (`id_client`) REFERENCES `client` (`id`) ON DELETE SET NUL ON UPDATE NO ACTION;

– Constraints for table `voucher`

ALTER TABLE `voucher`

ADD CONSTRAINT `client_voucher_fk` FOREIGN KEY (`id_client`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;

/*!40101 SET COLATION_CONNECTION=@OLD_COLATION_CONNECTION */;

Similar Posts