Creating databases for web applications Library. New example: student database. Homework: Complete class example. Catch up on source postings. Do creation and simple entry and retrieval for a database. Library? • Show information (ERD) and process (DFD) Simple example • Students: name, gpa, department • http://socialsoftware.purchase.edu/jeanine. meyer/studentexample/showstudents.php • http://socialsoftware.purchase.edu/jeanine. meyer/studentexample/showdepartments. php • http://socialsoftware.purchase.edu/jeanine. meyer/studentexample/enterstudent.html Storyboard createtable enterstudent.html enterstudent.php showstudents.php showdepartments.php Note • Plenty to add – improve look of enterstudent.html – provide better feedback – add edit student info function, probably based on displaying a list – add more display functions, such as top student in each department, all students with averages over a certain amount, ? – more information create the one table Fields id name department GPA So what should the SQL and what should all the code be? Write it down. <?php require("connectcode.php"); $tname = "students"; $fields = "sid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, sname CHAR(30), sgpa FLOAT(5,4), sdept CHAR(30)"; $query = "DROP TABLE students"; mysqli_query($link,$query); $query = "CREATE TABLE $tname ($fields)"; if (mysqli_query($link,$query)) { print ("The table, $tname, was created successfully.<br>\n"); } else { print ("The table, $tname, was not created. <br>\n"); } mysqli_close($link); ?> Adding a record to the students table • The enterstudent.html file does not use php. It displays a form that invokes enterstudent.php using the action attribute on the form. • Think about what the html file would look like…. enterstudent.html <html><head><title>Input student </title></head> <body> <form action="enterstudent.php"> Student Name <input type="text" name="sn"/><br/> Department <input type="text" name="sd"><br/> GPA <input type="input" name="sgpa" /><br/> <input type="submit" value="STORE"/> </form> </body> </html> Note • The names of the input fields of the form do not have to be consistent with the names of the fields in the database table. • Extra credit opportunity: Report on Ruby on Rails. This is an alternative to html and php that produces code that uses these connections. • The php code does insert slashes to prevent problems with names such as O'Bama. • … does check that gpa is a number. Could add a tighter check that it is a number between 0 and 5 (?). • The 0 for the sid field is a placeholder. The stored sid will be the autoincremented value. enterstudent.php <?php require("connectcode.php"); $sn =$_GET['sn']; $sn = ADDSLASHES($sn); $sd=$_GET['sd']; $sd = ADDSLASHES($sd); $sgpa = $_GET['sgpa']; if (!is_numeric($sgpa)) { print ("Bad GPA data."); } else { $query="INSERT INTO students VALUES ("; $query.="'0','$sn',$sgpa,'$sd')"; print ("query is $query. "); if (mysqli_query($link,$query)) { print ("Student record added successfully"); } Else { print ("failure to add student record "); } } mysqli_close($link); //this depends on db link ?> Note • Order of fields is important for the VALUES form of the INSERT statement. • There is another form: INSERT INTO students SET … Extra credit: research and see what works. showstudents.php <html> <head><title>List contents of students table</title></head><body> <?php require("connectcode.php"); $query="SELECT * FROM students"; $result=mysqli_query($link, $query); print("<table border='1'>"); print("<tr><th>Student</th><th>Department</th><th>GPA </th></tr>"); while ($row=mysqli_fetch_array($result)) { print("<tr>"); print("<td> ".$row['sname']."</td>"); print ("<td>".$row['sdept'] ."</td>"); print ("<td>".$row['sgpa']."</td>"); print ("</tr>"); } mysqli_close($link); ?> </table> </body> </html> Another enhancement • What to do when the table gets big? • Implement 'paging' • Put in buttons, perhaps using an a tag with a query string giving the page value • The SELECT statement has a LIMIT feature – SELECT …. LIMIT 1, 10 – SELECT …. LIMIT 11, 10 – $query = "SELECT ….. LIMIT " . $next . ", 10 " • Opportunity for research. showdepartments • Aggregate functions – count – average – sum –… • Use names (aliases) in the SELECT statement • ORDER BY • GROUP BY from showdepartments.php <?php require("connectcode.php"); $query="SELECT sdept, AVG(sgpa) as a, COUNT(*) as c FROM students GROUP BY sdept ORDER BY a DESC"; $result=mysqli_query($link, $query); print("<table border='1'>"); print("<tr><th>Department</th><th>Average GPA </th><th>COUNT </th></tr>"); while ($row=mysql_fetch_array($result)) { print("<tr>"); print("<td> ".$row['sdept']."</td>"); print ("<td>".$row['a'] ."</td>"); print ("<td>".$row['c']."</td>"); print ("</tr>"); } mysqli_close($link); ?> </table> Variation • Impose condition on the GROUPed data • http://socialsoftware.purchase.edu/jeanine. meyer/studentexample/showbigdepartmen ts.php • Change QUERY to $query="SELECT sdept, AVG(sgpa) as a, COUNT(*) as c FROM students GROUP BY sdept HAVING c>1 ORDER BY a DESC"; SELECT • WHERE condition and JOIN conditions are done on individual records. • HAVING condition is on GROUPed data. • Look at my examples AND use sources. Caution The word 'design' may refer to • Design (plan, structure, organization, definition) of the database and the application • The look of an application • One of my examples: the content of the product being produced is the design of a grid using pre-defined units. Systems design • Focus on information – what is the information and how do [things] relate – Entity relationship diagramming is a tool – Information may exist already in the organization • organizations may have products, perhaps customized, to hold their information • includes dates, versions, owners, etc. • Focus on function of application(s) – who does what – … using what information System design • slow down rush to implement • [start] documentation • Design and documentation may change as system is being built, deployed, refined…. • Still, goal is to decrease bugs ER diagram • Database holds – Tables. Table represents one type of entity Row in table holds information on one example of the entity – Row in table made up of • Attributes (aka fields) • Lines connecting tables indicate occurrence of attribute in one table that points to a row in another table (or that table) – What is the pointer? The id of the row. This is called a foreign key. • One mark of good design is robustness: ease of changing over time. File upload • What if the application requires users to upload files? – and asking them to use an ftp program not appropriate • The ISP may not permit this. CTS put restrictions on us. Why? fileupload1.html <html> <head><title>Get file name </title></head><body> <form action="fileupload2.php" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="file" name="file" id="file" /> <br /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html> fileupload2.php <?php if ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] == "image/pjpeg")) && ($_FILES["file"]["size"] < 200000)) { if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else fileupload2.php, cont. { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; if (file_exists($_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { $target = "uploads/"; $target .= $_FILES["file"]["name"]; move_uploaded_file ($_FILES["file"]["tmp_name"],$target); echo "Stored as: " . $target; } } } fileupload2.php else { echo "Invalid file"; } ?> Classwork/Homework Application: database for movies • Tables: movies, people_having_role_in_movie, people, nominations, ? • What processes would you want? – what maintenance functions do you want to have? – what questions would you want to ask JOINs • Some questions require data from multiple tables. • Tables can be connected by conditions, most typically connecting foreign keys with primary keys. • SELECT …. FROM table1 as t JOIN table2 as s ON t.fid = s.fid – The fid field may be primary key in table1. It is referenced by a field in table2. Multiple tables • SELECT p.pname, n.award FROM people as p JOIN roles as r ON p.pid = r.pid JOIN nominations as n ON r.rid = n.rid WHERE n.award IN (“BEST LEAD ACTOR”, “BEST LEAD ACTRESS”, “BEST SUPPORTING ACTOR”, “BEST SUPPORTING ACTRESS”) Tasks • List all movies by name, ordered by date • List all people by name with roles in a given movie, named $moviename • List all directors (by name), with movie (by name) ordered by movie name • List all movies by name in which someone was nominated for Best Lead Actor • List all movies by name in which someone was nominated for an acting category – Best Lead Actor, Best Lead Actress, Best Supporting Actor, Best Supporting Actress More • List movie name, person name, award name ordered by movie name • List movie name, number of people nominated, ordered from high to low – EXTRA CREDIT: figure out how not to count multiples for awards that have multiples (such as producer, technical awards • List winners: movie name, person name, award Research • Some questions require consideration of absent records – What movies were nominated (had people nominated) for Best Movie but not Best Director –? • Look up and study examples of LEFT JOINS Classwork/homework • Devise [more] SQL statements • Keep experimenting with creating tables, simple html and php scripts for data entry and for display.