Você está na página 1de 16

RelationalDatabaseManagementSystem(RDBMS)

3.1.RelationalDatabaseManagementSystem(RDBMS)
ADataBaseManagementSystemthatisbasedonarelationalmodeliscalledasRDBMS.Relationalmodel
isthemostsuccessfullyusedDataBaseManagementSystemModel(DBMS)model.
Relationalmodelrepresentsdataintheformofatable.Atableisatwodimensionalarraywhichcontains
rowsandcolumns.
Considerascenarioofacollegewhereweneedtomaintainhugeamountofstudentdetails.Allthese
studentdetailsarestoredinatableasmentionedinFigure3.1.
InFigure3.1,(asdiscussedinSection2ERmodel)studentsistheentityandNameisoneoftheattributes
ofthisstudentsentity.OtherattributesareRollNoandPhone.Thetablegivenbelowcontainsrowsand
columns.Eachrowcontainsdatarelatedtoanentity/students.Eachcolumncontainsthedatarelatedtoan
attribute.

Figure3.1:StudentTable
Figure3.1showsthedatarepresentedinrelationalmodelandthetermsthatareusedtorefertovarious
componentsofatable.Thetermsmentionedbelowareusedinrelationalmodel.
Tuple/Row
Asinglerowthatisavailableinthetableiscalledastuple.Eachrowinthetablerepresentsthedataofa
singleentity.Forexample,inFigure3.1s1,LouisFigo,454333representsarow.
Attribute/Column
Acolumninthetablestoresanattributeoftheentity.Forexample,inStudentstable(Figure3.1)LouisFigo,
Rahul,etc.aretheattributesashighlightedinfigure.
ColumnName
Eachcolumnthatisavailableinthetableisgivenaname.Thisnameisusedtorefertovaluesinthe
column.InStudentstable(Figure3.1),RollNo,NameandPhonearethecolumnnamesofthetable.
TableName
Eachtableisprovidedwithaname.Thenamethatisprovidedisusedtorefertothetable.Thenameofthe

tabledepictsthecontentsofthetable.IntheaboveFigure3.1,Studentsisthenameofthetable.
StructuredQueryLanguage(SQL)
Relationaldatabasemanagementsystems(RDBMS)useSQL(StructuredQueryLanguage)fordata
manipulationandretrieval.SQListhestandardlanguageforrelationaldatabasesystems.Itisanon
procedurallanguage.
Nonprocedurallanguagerequirestheprogrammertospecifywhattheprogramshoulddo,ratherthan
providingthesequentialstepsindicatinghowtheprogramshouldperformatask.
SQLCommandsaredividedintothreecategories,dependinguponwhattheydo:
DDL(DataDefinitionLanguage)
DML(DataManipulationLanguage)
DCL(DataControlLanguage)
RelatedVideo/MaterialLinks:

IntroductiontoDataDefinitionLanguage(DDL)
3.2.IntroductiontoDataDefinitionLanguage(DDL)
DataDefinitionLanguage(DDL)statementsareusedtocreateandmodifythestructureofyourtablesand
anyotherobjectsinthedatabase.SomeoftheDDLcommandsareCREATE,ALTERandDROP.
CREATEstatement
ACREATEstatementinSQLisusedtocreateatable.
ThegeneralsyntaxoftheCREATEstatementisgivenbelow:
Syntax:
CREATETABLEtable_name
(column_name1data_typeconstraints,
column_name2data_typeconstraints,
...
column_nameNdata_typeconstraints,
)
where,
table_nameisthenameofthetable
column_name1,column_name2,....,column_nameNisthenameofthecolumns
data_typeisthedatatypeforthecolumnlikechar,date,numberetc.
constraintsconstraintsareusedtovalidateorlimitthetypeofdatathatcangointoa
table.
Constraintsareoptionalforthecolumns.
Wewillfocusonafewconstraintsnow:
NOTNULL
PRIMARYKEY
FOREIGNKEY
UNIQUE
NOTNULL:TheNOTNULLconstraintenforcesacolumntonotacceptNULLvalues.Thismeansthatthis
columnmustcontainsomevaluewhileinsertingorupdatingarecord.
PRIMARYKEY:Primarykeyuniquelyidentifieseachrecordinthedatabase.Soaprimarykeycolumn
cannotcontainNULLvalues.(ReferSection2formoredetailsaboutPrimaryKey).
FOREIGNKEY:Aforeignkeyisacolumninatablethatmatchestheprimarykeycolumnofanothertable.
Theforeignkeycanbeusedtomaptwotables.(ReferSection2formoredetailsaboutForeignKey).
UNIQUE:Uniqueconstraintsareusedtomakesurethatnoduplicatevaluesareenteredinspecificcolumns
thatdonotparticipateinaprimarykey.AcolumndefinedasUNIQUEcancontainNULLvalues.
BasicSQLDATAtypes:
CHAR:TheCHARdatatypeisusedforstoringfixedlengthcharacterstringswithamaximumsizeof
2000bytes.TheCHAR(n)holdsfixedlengthofncharacters.
DATE:ItallowstodefinetheDateattributesasDatefieldsinthedatabase.HeretheDATEdatatype

storesyear,month,anddayvalues.
NUMBER:Itallowstodefineacolumnasnumberfield.Onlynumbervaluescanbestoredinthe
database.
Nowlet'sseehowtoimplementtheSQLquerieswithexamples:
Example1:
WiththehelpofCREATEstatement,let'screateStudentstablewithcolumnsasRollNo,NameandPhoneas
shownbelow.
CREATETABLEStudents(
RollNoNUMBERPRIMARYKEY,
NameCHAR(25)NOTNULL,
PhoneNUMBER
)
Here"Students"isthenameofthetable.RollNo,NameandPhonearethecolumnsofthetable.NUMBER
andCHAR(25)arethedatatypeswhichconveywhatkindofdatathatparticularcolumnwillhold.
HereRollNoisgivenasPRIMARYKEYwhichmeansthatthisparticularcolumnwillnotacceptanyduplicate
values.TheothertwocolumnsaredefinedasNOTNULLwhichconveysthatthesetwocolumnswillnot
acceptNULLvalues.
Note:NULLspecifiesthatthecolumndoesn'thaveanyvalueorthecolumnisempty.
Example2:
Let'sseeanotherexampleusingtheCreateStatement.
Thequerybelowisusedtocreate"employees"tablewithcolumnssuchasemployee_id,first_name,etc.
CREATETABLEemployees(
employee_idNUMBERPRIMARYKEY,
first_nameCHAR(10)NULL,
last_nameCHAR(10)NOTNULL,
emailCHAR(25)NOTNULL,
phone_numberNUMBERNOTNULL,
hire_dateDATENOTNULL,
job_idCHAR(10),
salaryNUMBER,
commission_pctNUMBER,
manager_idNUMBER,
department_idNUMBER
)
Example3:
InExample1andExample2weexplainedhowtocreateprimarykeyandNOTNULLconstrains.Nowlet's
seehowtoimplementforeignkeyconstraints.Toimplementforeignkeyweneedtwotablesthatare
dependentoneachother.
InExample2wehaveemployeestablewhichcontainsthedepartment_idasoneofthecolumnsbutdoes
nothavedepartmentdetails.Nowlet'screateadepartmenttablewhichcontainsdetailsofthedepartment
suchasdepartment_idanddepartmentname.
CREATETABLEdepartment(

department_idNUMBERPRIMARYKEY,
department_nameCHAR(10)
)
Considerascenariowhereweneedtoidentifythedepartment_nameofanemployee.Inthiscasethe
employeestableisdependentondepartmenttabletogetthedepartmentnamebasedonthecommon
columndepartment_id.Foreignkeyconstraintcomesintopictureinthiscase.Thesyntaxbelowcreates
foreignkey.(FormoredetailsaboutForeignkeyreferSection2).
CREATETABLEemployees(
employee_idNUMBERPRIMARYKEY,
first_nameCHAR(10)NULL,
last_nameCHAR(10)NOTNULL,
emailCHAR(25)NOTNULL,
phone_numberNUMBERNOTNULL,
hire_dateDATENOTNULL,
job_idCHAR(10),
salaryNUMBER,
commission_pctNUMBER,
manager_idNUMBER,
department_idNUMBERFOREIGNKEYREFERENCESdepartment(department_id)
)
DROPstatement
TheDROPcommandisusedtoremoveatablefromthedatabase.Ifyoudropatable,alltherowsinthe
tablearedeletedandthetablestructureisremovedfromthedatabasepermanently.Onceatableis
droppedusingDROPcommand,wecannotretrievethedata/tableback.Soweshouldbecarefulwhile
usingthiscommand.
Syntax:
DROPTABLEtable_name
Example1:
ThefollowingcommandisusedtopermanentlyremovetheStudentstablestructure/definitionalongwiththe
datathatwascreated.
DROPTABLEStudents
AfterexecutionoftheabovecommandtheentireStudentstableisremovedfromthedatabase.Wecannot
getbackanydataaboutStudentstable.
Example2:
Let'sseehowtheemployeestabledefinition/structureisremovedfromthedatabase.
DROPTABLEemployees
Afterexecutionoftheabovecommandtheentireemployeestableisremovedfromthedatabase.We
cannotgetbackanydataaboutemployeestable.
ALTERstatement
TheALTERstatementhelpstomodifythestructureofanexistingtableinthedatabase.
Onceyou'vecreatedatablewithinadatabase,youmaywishtomodifyit'sdefinitionatsomeinstance.
ALTERstatementallowsyoutomakechangestothestructureofatablewithoutdeletingorrecreatingit.
GeneralsyntaxofAlterstatementisgivenbelow.
Syntaxforaddingacolumntotheexistingtable:

ALTERTABLEtable_nameADDcolumn_namedata_type
Example:
Let'sseehowwecanalteroreditthestructureoftheStudentstablethatwecreatedusingCREATE
statementinSection3.2.1usingSQLqueries.Let'sassumethatwehavetoaddanewcolumncalled
'gender'totheexistingStudentstable.
ALTERTABLEStudentsADDgenderCHAR(10)
Intheaboveexamplethe"gender"columnwiththedatatypeasCHAR(10)hasbeenaddedtotheexisting
Studentstable.
Syntaxforaddingconstraints:
ALTERTABLEtable_nameADDCONSTRAINTclause
where:ACONSTRAINTclauseisoptionalintheaboveALTERTABLEstatementfordefiningtheconstraint.
Example:
IntheexamplebelowUniqueconstraintisappliedtoPhonecolumninordertoavoidduplicatephone
numbersgettinginsertedintothetable.
ALTERTABLEemployeesADDUNIQUEPhone
TheconstraintUNIQUEhasbeenaddedoncolumnPhoneofemployeestabletoshowuniquedata.

IntroductiontoDataManipulationLanguage(DML)
3.3.IntroductiontoDataManipulationLanguage(DML)
Datamanipulationlanguage(DML)isafamilyofcomputerlanguagethatincludescommandswhichpermit
userstomanipulatedatainadatabase.Thismanipulationinvolvesinsertingdataintodatabasetables,
retrievingexistingdata,deletingdatafromexistingtablesandmodifyingexistingdata.
DMLcommands:
INSERTToaddanewrowintoatable
UPDATEToupdateexistingrecordswithinatable
DELETETodeleterecordsinatable
SELECTToretrieverecordsfromatable
INSERTStatement
TheINSERTstatementinsertsnewrowsintoanexistingtable.
ThesyntaxforINSERTstatementisasfollows.
Syntax:
INSERTINTOtable_name(col1,col2,col3,....)
VALUES(vallue1,value2,value3,.....)
Example1:
Nowlet'sseehowtoinsertthedetailsofstudentsintoStudentstable.Thefollowingisthestructureofthe
Studentstable.Let'sseehowtoinsertthedetailsofastudentnamedDavid.

Table3.1
InthequerygivenbelowRollNo,Name,PhoneandGenderarethecolumnsdefinedintheStudentstable.
UsingINSERTstatementthecorrespondingvalues100,David,9830028200,Maleareinsertedintothose
columns.
INSERTINTOStudents(RollNo,Name,Phone,Gender)
VALUES(100,'David',9830028200,'Male')
Similarly,wecaninsertdetailsofanotherstudentnamed'Peter'.Let'strytoignoreacolumnwhichaccepts
NULLvalueduringinsertion.
INSERTINTOStudents(RollNo,Name,Gender)VALUES(200,'Peter','Male')
Intheabovequerywehavegivenvaluesonlyforthreecolumns(RollNo,Name,Gender).Thoughwedidn't
mentionPhone,therecordwillbesuccessfullyinsertedbecauseitisnotmandatorytoprovidevaluesforthe
columnswhichcanacceptNULLvaluesduringinsertion.InStudentstablePhoneandGenderarethe
columnswhichcanacceptNULLvalues.ForPeter'srecordPhonecolumnwillbeempty.
Thedataweinsertedisrepresentedinthetablebelow:

Table3.2
Example2:
Letusassumeemployeestablestructureasbelow:

Table3.3
Query:
INSERTINTOemployees(First_Name,Last_Name,Email,Phone_Number,
Hire_Date,Job_ID,Salary,Commission_PCT,Manager_ID,Age,Department_ID)
VALUES('George','Gordon','GGORDON',6505062222,
'01JAN07','SA_REP',9000,.1,148,25,80)
Result:
ERRORatline1:
ORA01400:cannotinsertNULLinto("E668292"."EMPLOYEES"."EMPLOYEE_ID")
Intheabovequerywearetryingtoinsertthedetailsofanemployeewithoutprovidingvaluefor
Employee_IDcolumn.Employee_IDcolumnisaNOTNULLcolumn.Soitismandatorytoprovidevaluefor
thesame.SincewetriedtoinsertsomedataexcludingtheNOTNULLcolumnvalue,theexecutionofthe
querygivesanerror.Sincewedidn'tgiveanyvaluefortheEmployee_IDcolumnthevaluethatwillgetinto
thetablewouldbeNULL.Soithasthrownaserroras"cannotinsertNULLintoEMPLOLYEE_IDcolumn".
Let'snowinsertarowbyprovidingEmployee_IDcolumnvalue.
INSERTINTOemployees
(Employee_ID,First_Name,Last_Name,Email,Phone_Number,
Hire_Date,Job_ID,Salary,Commission_PCT,Manager_ID,Age,Department_ID)
VALUES(10,'George','Gordon','GGORDON',6505062222,
'01JAN07','SA_REP',9000,.1,148,25,80)
Insertinganotheremployee:
INSERTINTOemployees
(Employee_ID,First_Name,Last_Name,Email,Phone_Number,
Hire_Date,Job_ID,Salary,Commission_PCT,Manager_ID,Age,Department_ID)
VALUES(11,'James','Keats','j_keats@gm',6505062221,
'01JAN07','SA_REP',7000,.1,148,25,80)
Theinserteddataisrepresentedintableformatbelow:

Table3.4
SELECTStatement
Selectstatementisusedtoretrievethedatafromthedatabasetable.
GeneralsyntaxoftheSelectstatementisgivenbelow:
Syntax:
SELECTcolumn_listFROMtable_nameWHEREsearch_condition
where
column_listincludesoneormorecolumnsfromwhichdataisretrieved.
table_nameisthenameofthetablefromwhichtheinformationisretrieved.
search_conditionspecifiestheconditionsbasedonwhichrowswillberetrieved.
ThethreeclausesusedintheSELECTstatement:

Table3.5
Example1:
IfwewanttoviewthedetailsofallstudentsafterinsertingthevaluesintheStudentstable,thequerybelow
canbeexecuted.
SELECT*FROMStudents
Result:

Table3.6
Here*denotesallthecolumnsandrowsofthetable.
Example2:
Let'sassumethatwewanttoselectarowfromStudentstablewhoserollnois200.
Toretrievethisthefollowingqueryisexecuted.
SELECTnameFROMStudentsWHERERollNo=200
Result:

Table3.7
Example3:

Nowlet'sconsiderascenariowhereweneedtoretrievetheSalaryfromemployeestablewhosefirstname
isGeorge.Thequeryforthescenariowillbeasfollows:
SELECTSalaryFROMemployeesWHEREfirst_name='George'
TherearechancesthattherearemorethanoneemployeeswithfirstnameasGeorge.Theabovequerywill
retrievealltheemployeeswhosefirstnameisGeorge.Butifweneedonlyonespecificemployeewhosefirst
nameisGeorgethenwecanaddonemoreconditioninWHEREclausewhichwillhelpinretrievingtheexact
requireddata.
SELECTSalaryFROMemployees
WHEREfirst_name='George'ANDemployee_id=10
Result:

Table3.8Intheabovequerywehaveaddedtwoconditionswiththehelpofthe"AND"keyword.ANDchecks
forboththeconditionsandwillretrievetherecordwhichmatchesboth.Sosalaryoftheemployee(i.e
Georgeasshowninresult)isretrievedfromtheemployeestablewhoseFIRST_NAMEis"George"and
EMPLOYEE_IDisequalto10.Sofarwesawhowtoretrievedatafromonetable.Nowlet'sseehowto
retrievedatafrommorethanonetable.
ToretrieveorcombinedatafrommorethanonetableweuseJoins.
Joins:
Joincommandisusedtocombinerecordsfromtwoormoretablesinadatabase.Joincommandcreatesa
setthatcanbesavedasatableorusedasitis.
AJoinisameansofcombiningfieldsfromtwotablesbyusingvaluescommontoeachother.
AJoinconditioncanbeusedintheWHEREclauseofSELECT,UPDATE,DELETEstatements.(Refer
Section2inthisdocumentformoredetails)
Thefollowingisthesyntaxforjoiningtwotables:
SELECTcol1,col2,col3...FROMtable_name1,table_name2
WHEREtable_name1.col2=table_name2.col1Example:
Let'sassumethatDepartmenttablehasthefollowingdata.

Table3.9Theemployeestablehasthefollowingdata:

Table3.10ThecolumnthatiscommonbetweenthetwotablesisDepartment_ID.SousingDepartment_ID
wecanjoinDepartmenttableandemployeestable.Pleasefindbelowqueryforthesame.
SELECTemployee_Id,first_name,department_name,department_id
FROMdepartment,employees
WHEREdepartment.department_id=employees.department_id
Result:

Table3.11Heredatafromemployeestableanddepartmenttablearejoinedanddisplayed.
Department_IdfromdepartmenttableiscomparedwithDepartment_Idfromemployeestableandthe
recordsthathavesamevalueforDepartment_Id(i,e.80)havebeendisplayed.UPDATEStatement
Let'seehowtomodifytheexistingrowsinatable.
InSection3.3.1wesawhowtoinserttherecordsintoatable.Herewewillseehowtoupdatetheinserted
records.
TheUPDATEstatementmodifiesthesetofexistingtablerows.
GeneralsyntaxfortheUPDATEstatementisgivenbelow.
Syntax:
UPDATEtable_name
SET(column_name1=value,column_name2=value,..)
WHEREcondition
Note:TheWHEREclauseintheabovesyntaxspecifieswhichrecordorrecordsshouldbeupdated.All
recordswillbeupdated,ifweomittheWHEREclauseinUPDATEstatement.Let'sseeafewexamplesfor
theUPDATEstatement.
Example1:

Table3.12Let'supdatetheName"David"inthestudentstablesto"John".
Weusethebelowqueryforthesame.
UPDATEstudentsSETname='John'WHERErollno=100
Result:
1rowupdated.
Studentstablewilllooklikethisnow:

Table3.13Example2:
employeestablehasthefollowingdata:

Table3.14Nowwewanttoupdatethesalaryoftheemployeewhosemanager_IDis148.
Weusethebelowqueryforthesame.
UPDATEemployeesSETsalary=10500WHEREmanager_id=148
Result:
2rowsupdated.
Intheabovequeryemployeestableisupdatedwiththesalaryvalue10500fortherowswhichhavethe
manager_idas148.

Thereweretworowswhichhadmanager_idas148andtheyhavebeenupdatedwithsalaryvalueas10500
from9000and7000respectively.
employeestablewilllooklikethisnow:

Table3.15
DELETEStatement
TheDELETEstatementisusedtodeletetherowsfromatable.
TheDELETEstatementsyntaxisgivenbelow.
Syntax:
DELETEFROMtable_nameWHEREcondition
IfweincludetheWHEREclause,thestatementdeletesonlythoserecordsthatsatisfythecondition.Ifwe
omittheWHEREclause,thestatementdeletesallrecordsfromthetable,butthetablestillexistswithout
records.
Example1:
Studentstablehasthedataasshownbelow:

Table3.16IfwewanttodeletearowfromtheabovetablewhoseRollNois100,weusethebelowquery.
DELETEFROMStudentsWHEREROLLNO=100
Result:
1rowdeleted.
Afterdeletingtherecord,Studentstablewilllooklikethis:

Table3.17Example2:
employeestablehasthefollowingdata:

Table3.18Nowlet'sdeletetheemployeedetailswhosehiredateis1stJan07.
DELETEFROMemployeesWHEREhire_date='01JAN07'
Result:
2rowsdeleted.
TworowswhichhavetheHire_Datevalueas'01JAN07'havebeendeletedfromemployeestable(Refer
Example2ofSec3.2.1).
Note:TheDELETEstatementisdifferentfromtheDROPstatement.TheDELETEstatementdeletessome
(orall)datafromthetablebutthetableexistsinthedatabase.TheDROPstatementremovesthetable
permanentlyfromthedatabase.

IntroductiontoDCL(DataControlLanguage)
3.4.IntroductiontoDCL(DataControlLanguage)
TheDataControlLanguage(DCL)componentoftheSQLlanguageanditisusedtoprovideprivilegesto
theuserstoaccessortomanipulatethedatabase.Thefollowingaretwomaincommands:
GRANTThiscommandisusedtograntprivilegestoauser.
REVOKEThiscommandisusedtorevoke(remove)privilegesfromauser.
GRANTcommand
Inordertodoanythingwithinadatabaseyoumustbegiventheappropriateprivileges.Databaseoperates
inaclosedsystemwhereyoucannotperformanyactionatallunlessyouhavebeenauthorizedtodoso.
Thisincludesloggingontothedatabase,creatingtables,manipulatingdata(ieselect,insert,updateand
delete)intablescreatedbyotherusers,etc.
Syntax:
GRANTprivilege_nameONtable_nameTOuser_name
Where,
privilege_nameistheaccessrightorprivilegegrantedtotheuser.
table_nameisthenameofthetableinthedatabase.
user_nameisthenameoftheusertowhomanaccessrightisbeinggranted.
Example:
GRANTSELECTONemployeesTOuser10
ThiscommandgrantsaSELECTpermissiononemployeestabletouser10.
REVOKEcommand
TheSQLcommandisusedtorevokeaprivilegeonatable.
Syntax:
REVOKEprivilege_nameONtable_nameFROMuser_name
Where,
privilege_nameistheaccessrightorprivilegerevokedfromtheuser.
table_nameisthenameofthetableinthedatabase.
user_nameisthenameoftheuserfromwhomanaccessrightisbeingrevoked.
Example:
REVOKESELECTONemployeesFROMuser10
ThiscommandwillREVOKEaSELECTprivilegeonemployeestablefromuser10.IfyouREVOKESELECT
privilegeonatablefromauser,thentheuserisnotabletoSELECTdatafromthattableanymore.

Summary:
3.5.Summary:
DDL
DataDefinitionLanguage(DDL)statementsareusedtodefine,modifyorremovethetablestructure.
Commands:
CREATEThiscommandisusedtocreateobjectsinthedatabase
ALTERItaltersthestructureofthedatabase
DROPThiscommandisusedtodeletetheobjectfromthedatabase
DML
DataManipulationLanguage(DML)statementsareusedformanagingdatawithinthedatabase.
Commands:
SELECTretrievedatafromthetable
INSERTThedataisinsertintoatable
UPDATEItupdatesexistingdatawithnewdatawithinatable
DELETEItdeletestherecordsfromatablebutthespacefortherecordsremain
DCL
DataControlLanguage(DCL)statements:
Commands:
GRANTItgivestheuser'saccessprivilegestodatabase
REVOKEwithdrawaccessprivilegeswhichwasalreadyprovidedtotheuser
3.5.Summary:
DDL
DataDefinitionLanguage(DDL)statementsareusedtodefine,modifyorremovethetablestructure.
Commands:
CREATEThiscommandisusedtocreateobjectsinthedatabase
ALTERItaltersthestructureofthedatabase
DROPThiscommandisusedtodeletetheobjectfromthedatabase
DML
DataManipulationLanguage(DML)statementsareusedformanagingdatawithinthedatabase.
Commands:
SELECTretrievedatafromthetable
INSERTThedataisinsertintoatable
UPDATEItupdatesexistingdatawithnewdatawithinatable
DELETEItdeletestherecordsfromatablebutthespacefortherecordsremain
DCL
DataControlLanguage(DCL)statements:
Commands:
GRANTItgivestheuser'saccessprivilegestodatabase
REVOKEwithdrawaccessprivilegeswhichwasalreadyprovidedtotheuser

Você também pode gostar