You are on page 1of 25

MySql - designing Your Web Database

mysql -h hostname -u username p Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 to server version: 5.1.25-rccommunity MySQL Community Server (GPL) Type help; or \h for help. Type \c to clear the buffer. mysql> mysql> create database dbname;

c:\xampp\> cd mysql c:\xampp\mysql> cd bin c:\xampp\mysql\bin> mysql u root show datatbases; use wiki; show tables; describe job; create table miki ( isbn char(13) not null primary key, author char(50) ); show tables; drop table miki;

The identifying column in a table is called the key or the primary key

The complete set of table designs for a database is called the database schema. Underlined terms in the schema are primary keys in the relation in which they are underlined. Italic terms are foreign keys in the relation in which they appear italic. Foreign keys represent a relationship between data in two tables. Three basic kinds of relationships exist in a relational database.They are classified according to the number of elements on each side of the relationship. Relationships can be either one-toone, one-to-many, or many-to-many. A one-to-one relationship means that one of each thing is used in the relationship. In a one-to-many relationship, one row in one table is linked to many rows in another table. In a many-to-many relationship, many rows in one table are linked to many rows in another table. Example In the Book-O-Rama example, you want to store information about customers, the books that you sell, and details of the orders.The customers all have names and addresses. Each order has a date, a total amount, and a set of books that were ordered. Each book has an International Standard Book Number (ISBN), an author, a title, and a price.

Avoid Storing Redundant Data

Three kinds of update anomalies need to be avoided: modification, insertion, and deletion anomalies. Use Atomic Column Values

This table provides a link between the Orders and Books tables.This type of table is common when a many-to-many relationship exists between two objects; in this case, one order might consist of many books, and each book can be ordered by many people.

Choose Sensible Keys Make sure that the keys you choose are unique. In this case, we created a special key for customers (CustomerID) and for orders (OrderID) because these real-world objects might not naturally have an identifier that can be guaranteed to be unique.You dont need to create a unique identifier for books; this has already been done, in the form of an ISBN.

Avoid Designs with Many Empty Attributes

Web Database Architecture

MySQLs Privilege System

The general sintax: GRANT privileges [columns] ON item TO user_name [IDENTIFIED BY password] [REQUIRE ssl_options] [WITH [GRANT OPTION | limit_options] ]

Privileges - comma-separated list of privileges Columns - single column name or a comma-separated list of column names. Item - database or table to which the new privileges apply. *.* grant privileges on all the databases (global privileges) dbname.* - all tables in a database dbname.tablename - single table as dbname.tablename & some specific columns in the columns placeholder - specific columns by specifying user_name - name you want the user to log in as in MySQL. The user_name in MySQL can also contain a hostname (laura-interpreted as laura@localhost) and password - password you want the user to log in with. REQUIRE clause - user must connect via Secure Sockets Layer (SSL) and specify other SSL options. WITH GRANT OPTION - allows the specified user to grant her own privileges to others. For example: MAX_QUERIES_PER_HOUR n MAX_UPDATES_PER_HOUR n MAX_CONNECTIONS_PER_HOUR n Privileges are stored in five system tables, in the database called mysql.These five tables are called : mysql.user mysql.db mysql.tables_priv mysql.columns_priv As an alternative to GRANT, you can alter these tables directly.

Examples Using GRANT and REVOKE To set up an administrator, you can type mysql> grant all -> on * -> to fred identified by mnb123 -> with grant option; This command grants all privileges on all databases to a user called Fred with the password mnb123 and allows him to pass on those privileges. Chances are you dont want this user in your system, so go ahead and revoke him: mysql> revoke all privileges, grant -> from fred;

Now you can set up a regular user with no privileges: mysql> grant usage -> on books.* -> to sally identified by magic123; You can give her the appropriate privileges: mysql> grant select, insert, update, delete, index, alter, create, drop -> on books.* -> to sally; Note that you dont need to specify Sallys password to give her privileges. If you decide that Sally has been up to something in the database, you might decide to reduce her privileges: mysql> revoke alter, create, drop -> on books.* -> from sally; And later, when she doesnt need to use the database any more, you can revoke her privileges altogether: mysql> revoke all -> on books.* -> from sally;

Setting Up a User for the Web

mysql> grant select, insert, delete, update -> on books.* -> to bookorama identified by bookorama123; You can run an existing SQL file through MySQL by typing: > mysql -h host -u bookorama -D books -p < bookorama.sql create table customers ( customerid int unsigned not null auto_increment primary key, name char(50) not null, address char(100) not null, city char(30) not null ); create table orders ( orderid int unsigned not null auto_increment primary key, customerid int unsigned not null,

amount float(6,2), date date not null ); create table books ( isbn char(13) not null primary key, author char(50), title char(100), price float(4,2) ); create table order_items ( orderid int unsigned not null, isbn char(13) not null, quantity tinyint unsigned, primary key (orderid, isbn) ); create table book_reviews ( isbn char(13) not null primary key, review text ); NOT NULL - that all the rows in the table must have a value in this attribute. If it isnt specified, the field can be blank (NULL). AUTO_INCREMENT - special MySQL feature you can use on integer columns. It means if you leave that field blank when inserting rows into the table, MySQL will automatically generate a unique identifier value.The value will be one greater than the maximum value in the column already.You can have only one of these in each table. PRIMARY KEY - after a column name specifies that this column is the primary key for the table. Entries in this column have to be unique. MySQL automatically indexes this column. UNSIGNED - after an integer type means that it can have only a zero or positive value. Understanding the Column Types customerid int unsigned not null auto_increment primary key, name char(50) not null, amount float(6,2) , date date not null quantity tinyint unsigned, multicolumn primary keys need to be specified with a special primary key clause primary key (orderid, isbn) review text

mysql> show tables; 8

MySQL then displays a list of all the tables in the database: +-----------------+ | Tables in books | +-----------------+ | book_reviews | | books | | customers | | order_items | | orders | +-----------------+ 5 rows in set (0.06 sec) You can also use show to see a list of databases by typing mysql> show databases;

mysql> describe books; MySQL then displays the information you supplied when creating the database: +--------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+------------+------+-----+---------+-------+ | isbn | char(13) | NO | PRI | NULL | | | author | char(50) | YES | | NULL | | | title | char(100) | YES | | NULL | | | price | float(4,2) | YES | | NULL | | +--------+------------+------+-----+---------+-------+ 4 rows in set (0.00 sec) These commands are useful to remind yourself of a column type or to navigate a database that you didnt create. If you find that you are running many queries on a column that is not a key, you may want to add an index on that column to improve performance.You can do this with the CREATE INDEX statement. The general form of this statement is CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_column_name [(length)] [ASC|DESC], ...]) (FULLTEXT indexes are for indexing text fields) The optional length field allows you to specify that only the first length characters of the field will be indexed. You can also specify that an index should be ascending (ASC) or descending (DESC); the default is ascending.



String Types String types fall into three groups. First, there are plain old stringsthat is, short pieces of text.These are the CHAR (fixed-length character) and VARCHAR (variable-length character) types.You can specify the width of each. Columns of type CHAR are padded with spaces to the maximum width regardless of the size of the data, whereas VARCHAR columns vary in width with the data. Second, there are TEXT and BLOB types.These types, which come in various sizes, are for longer text or binary data, respectively. BLOBs, or binary large objects, can hold anything you likefor example, image or sound data. The third group has two special types: SET and ENUM.The SET type specifies that values in this column must come from a particular set of specified values. Column values can contain more than one value from the set.You can have a maximum of 64 things in the specified set. ENUM is an enumeration. It is very similar to SET, except that columns of this type can have only one of the specified values or NULL, and you can have a maximum of 65,535 things in the enumeration.


Inserting Data into the Database

The usual form of an INSERT statement is INSERT [INTO] table [(column1, column2, column3,...)] VALUES (value1, value2, value3,...); For example, to insert a record into Book-O-Ramas customers table, you could type insert into customers values (NULL, 'Julie Smith', '25 Oak Street', 'Airport West'); If you want to fill in only some of the columns, or if you want to specify them in a different order, you can list the specific columns in the columns part of the statement. For example, insert into customers (name, city) values (Melissa Jones, Nar Nar Goon North);

You can also achieve the same effect with the following syntax: insert into customers set name = Michael Archer, address = 12 Adderley Avenue, city = Leeton;


use books; insert into customers values (3, Julie Smith, 25 Oak Street, Airport West), (4, Alan Wong, 1/47 Haines Avenue, Box Hill), (5, Michelle Arthur, 357 North Road, Yarraville); insert (NULL, (NULL, (NULL, (NULL, into orders values 3, 69.98, 2007-04-02), 1, 49.99, 2007-04-15), 2, 74.98, 2007-04-19), 3, 24.99, 2007-05-01);

insert into books values (0-672-31697-8, Michael Morgan, Java 2 for Professional Developers, 34.99), (0-672-31745-1, Thomas Down, Installing Debian GNU/Linux, 24.99), (0-672-31509-2, Pruitt, et al., Teach Yourself GIMP in 24 Hours, 24.99), (0-672-31769-9, Thomas Schenk, Caldera OpenLinux System Administration Unleashed, 49.99); insert into order_items values (1, 0-672-31697-8, 2), (2, 0-672-31769-9, 1), (3, 0-672-31769-9, 1), (3, 0-672-31509-2, 1), (4, 0-672-31745-1, 3); insert into book_reviews values (0-672-31697-8, The Morgan book is clearly written and goes well beyond most of the basic Java books out there.);

Retrieving Data from the Database

The basic form of a SELECT is SELECT [options] items [INTO file_details] FROM tables [ WHERE conditions ] [ GROUP BY group_type ] [ HAVING where_definition ] [ ORDER BY order_type ] [LIMIT limit_criteria ] [PROCEDURE proc_name(arguments)] [lock_options] ; select name, city from customers; This query has the following output, assuming that youve entered the sample data :


+-----------------+--------------------+ | name | city | +-----------------+--------------------+ | Julie Smith | Airport West | | Alan Wong | Box Hill | | Michelle Arthur | Yarraville | | Melissa Jones | Nar Nar Goon North | | Michael Archer | Leeton | +-----------------+--------------------+

Retrieving Data with Specific Criteria

To access a subset of the rows in a table, you need to specify some selection criteria.You can do this with a WHERE clause. For example, select * from orders where customerid = 3; selects all the columns from the orders table, but only the rows with a customerid of 3. Heres the output: +---------+------------+--------+------------+ | orderid | customerid | amount | date | +---------+------------+--------+------------+ | 1 | 5 | 69.98 | 2007-04-02 | | 4 | 5 | 24.99 | 2007-05-01 | +---------+------------+--------+------------+ The WHERE clause specifies the criteria used to select particular rows.

Retrieving Data from Multiple Tables

Often, to answer a question from the database, you need to use data from more than one table. To put this information together in SQL, you must perform an operation called a join. This simply means joining two or more tables together to follow the relationships between the data. select orders.orderid, orders.amount, from customers, orders where = Julie Smith and customers.customerid = orders.customerid; The output of this query is: +---------+--------+------------+ | orderid | amount | date | +---------+--------+------------+ | 1 | 69.98 | 2007-04-02 | | 4 | 24.99 | 2007-05-01 | +---------+--------+------------+


By listing two tables, you also specify a type of join, possibly without knowing it.The comma between the names of the tables is equivalent to typing INNER JOIN or CROSS JOIN. This is a type of join sometimes also referred to as a full join, or the Cartesian product of the tables.

Using Other Names for Tables: Aliases

Other names for tables are called aliases. They are often handy as shorthand.


select from customers as c, orders as o, order_items as oi, books as b where c.customerid = o.customerid and o.orderid = oi.orderid and oi.isbn = b.isbn and b.title like %Java%;

Retrieving Data in a Particular Order

If you want to display rows retrieved by a query in a particular order, you can use the ORDER BY clause of the SELECT statement.This feature is handy for presenting output in a good human-readable format. The ORDER BY clause sorts the rows on one or more of the columns listed in the SELECT clause. For example, select name, address from customers order by name; (=

order by name asc; order by name desc;)

This query returns customer names and addresses in alphabetical order by name, like this: +-----------------+--------------------+ | name | address | +-----------------+--------------------+ | Alan Wong | 1/47 Haines Avenue | | Julie Smith | 25 Oak Street | | Michelle Arthur | 357 North Road | +-----------------+--------------------+ 17

Grouping and Aggregating Data

select avg(amount) from orders; The output is something like this: +-------------+ | avg(amount) | +-------------+ | 54.985002 | +-------------+

select customerid, avg(amount) from orders group by customerid; When you use a GROUP BY clause with an aggregate function, it actually changes the behavior of the function. Instead of giving an average of the order amounts across thetable, this query gives the average order amount for each customer (or, more specifically, for each customerid): +------------+-------------+ | customerid | avg(amount) | +------------+-------------+ | 1 | 49.990002 | | 2 | 74.980003 | | 3 | 47.485002 | +------------+-------------+


In addition to grouping and aggregating data, you can actually test the result of an aggregate by using a HAVING clause. It comes straight after the GROUP BY clause and is like a WHERE that applies only to groups and aggregates. To extend the previous example, if you want to know which customers have an average order total of more than $50, you can use the following query: select customerid, avg(amount) from orders group by customerid having avg(amount) > 50; Note that the HAVING clause applies to the groups.This query returns the following output: +------------+-------------+ | customerid | avg(amount) | +------------+-------------+ | 2 | 74.980003 | +------------+-------------+

Using Subqueries
The most common use of subqueries is to use the result of one query in a comparison in another query. For example, if you wanted to find the order in which the amount ordered was the largest of any of the orders, you could use the following query: select customerid, amount from orders where amount = (select max(amount) from orders); This query gives the following results: +------------+--------+ | customerid | amount | +------------+--------+ | 2 | 74.98 | +------------+--------+ One clause of the SELECT statement that can be particularly useful in Web applications is LIMIT. It is used to specify which rows from the output should be returned.This clause takes two parameters: the row number from which to start and the number of rows to return. This query illustrates the use of LIMIT: select name from customers limit 2, 3; This query can be read as, Select name from customers, and then return 3 rows, starting from row 2 in the output.


Updating Records in the Database

In addition to retrieving data from the database, you often want to change it. The usual form of an UPDATE statement is UPDATE [LOW_PRIORITY] [IGNORE] tablename SET column1=expression1,column2=expression2,... [WHERE condition] [ORDER BY order_criteria] [LIMIT number] Lets look at some examples. If you want to increase all the book prices by 10%, you can use an UPDATE statement without a WHERE clause: update books set price = price*1.1; If, on the other hand, you want to change a single rowsay, to update a customers address you can do it like this: update customers set address = 250 Olsens Road where customerid = 4;

Altering Tables After Creation

In addition to updating rows, you might want to alter the structure of the tables within your database. For this purpose, you can use the flexible ALTER TABLE statement.The basic form of this statement is


ALTER TABLE [IGNORE] tablename alteration [, alteration ...]


Deleting Records from the Database

Deleting rows from the database is simple.You can do this using the DELETE statement, which generally looks like this: DELETE [WHERE [ORDER [LIMIT [LOW_PRIORITY] [QUICK] [IGNORE] FROM table condition] BY order_cols] number]

If you write delete from table; on its own, all the rows in a table will be deleted, so be careful! Usually, you want to delete specific rows, and you can specify the ones you want to delete with a WHERE clause: delete from customers where customerid=5;

Dropping Tables
At times, you may want to get rid of an entire table.You can do this with the DROP TABLE statement.This process is very simple, and it looks like this: 22

DROP TABLE table; This query deletes all the rows in the table and the table itself, so be careful using it.

Dropping a Whole Database

You can go even further and eliminate an entire database with the DROP DATABASE statement, which looks like this: DROP DATABASE database; This query deletes all the rows, all the tables, all the indexes, and the database itself, so it goes without saying that you should be somewhat careful using this statement.

Accessing Your MySQL Database from the Web with PHP

<html> <head> <title>Book-O-Rama Catalog Search</title> </head> <body> <h1>Book-O-Rama Catalog Search</h1> <form action="results.php" method="post"> Choose Search Type:<br /> <select name="searchtype"> <option value="author">Author</option> <option value="title">Title</option> <option value="isbn">ISBN</option> </select> <br /> Enter Search Term:<br /> <input name="searchterm" type="text" size="40"/> <br /> <input type="submit" name="submit" value="Search"/> </form> </body> </html>

<html> <head> <title>Book-O-Rama Search Results</title> </head> <body> <h1>Book-O-Rama Search Results</h1> <?php // create short variable names $searchtype=$_POST['searchtype']; $searchterm=trim($_POST['searchterm']);


if (!$searchtype || !$searchterm) { echo 'You have not entered search details. Please go back and try again.'; exit; } if (!get_magic_quotes_gpc()){ $searchtype = addslashes($searchtype); $searchterm = addslashes($searchterm); } @ $db = new mysqli('localhost', 'bookorama', 'bookorama123', 'books'); if (mysqli_connect_errno()) { echo 'Error: Could not connect to database. Please try again later.'; exit; } $query = "select * from books where ".$searchtype." like '%".$searchterm."%'"; $result = $db->query($query); $num_results = $result->num_rows; echo "<p>Number of books found: ".$num_results."</p>"; for ($i=0; $row echo echo echo echo echo echo echo echo echo } $i <$num_results; $i++) { = $result->fetch_assoc(); "<p><strong>".($i+1).". Title: "; htmlspecialchars(stripslashes($row['title'])); "</strong><br />Author: "; stripslashes($row['author']); "<br />ISBN: "; stripslashes($row['isbn']); "<br />Price: "; stripslashes($row['price']); "</p>";

$result->free(); $db->close(); ?> </body> </html>

You begin the script by stripping any whitespace that the user might have inadvertently entered at the beginning or end of his search term.You do this by applying the function trim(). You also use stripslashes() on the data coming back from the database. If the magic quotes feature is turned on, the data will have slashes in it when it comes back from the database, so you need to take them out. If you prefer a procedural approach, mysqli allows for this, too. To connect in a procedural fashion, you use 24


If you want to change the default database, you can do so with the mysqli_select_db() function. It can be accessed as either

or as
mysqli_select_db(db_resource, db_name)

To actually perform the query, you can use the mysqli_query() function. Before doing this, however, its a good idea to set up the query you want to run:
$query = "select * from books where ".$searchtype." like '%".$searchterm."%'";

You can now run the query:

$result = $db->query($query);

or, if you want to use the procedural interface, you use

$result = mysqli_query($db, $query);

A large variety of functions is available to break the results out of the result object or identifier in different ways.The result object or identifier is the key to accessing the rows returned by the query. In this example, you counted the number of rows returned and also used the mysqli_fetch_assoc() function. When you use the objectoriented approach, the number of rows returned is stored in the num_rows member of the result object, and you can access it as follows: $num_results = $result->num_rows; When you use a procedural approach, the function mysqli_num_rows() gives you the number of rows returned by the query.You should pass it the result identifier, like this: $num_results = mysqli_num_rows($result); Its useful to know this if you plan to process or display the results, because you now know how many there are and can loop through them: for ($i=0; $i <$num_results; $i++) { // process results } You can free up your resultset by calling either $result->free(); or mysqli_free_result($result); You can then use $db->close(); or mysqli_close($db); to close a database connection.

Putting New Information in the Database na vjebama THE END !