An Introduction to MySQL 5: Views

An Introduction to MySQL 5: Views

Tutorial Details
  • Program: MySQL
  • Difficulty: Moderate
  • Estimated Completion Time: 10 Minutes

The MySQL 5 series introduced quite a few changes. Triggers and stored procedures were two of the big ticket items. One of the lesser known additions, at least from the amount of writing on the subject, is the introduction of views. While after a quick look at MySQL views, you might not see the obvious advantages, they’re there if you dig into them just a bit.


Introduction: What is a View

“A View is nothing more than a pseudo table doing the work of a defined query.”

In short, the easiest way to look at a view is that it is just a stored query which mimics a table. It’s nothing more than a pseudo table doing the work of a defined query. It doesn’t add any functionality, such as changing variables, nor does it fire other queries when something else happens. Views just sit there, fat dumb and happy doing what you defined them to do.

On first blush, this doesn’t sound like that big of a deal, but if you dig past the surface, you can start seeing some of the power of the lowly view. I am not going to say that views will change your life, but I will tell you that they will make the job of database interaction a little easier to work with. They will make your job a little easier when you make major version changes in your interaction layer. They will also make some difficult tasks such as dynamic reporting a little more efficient and a little easier to work with. I’ll take a little easier any day of the week.

With anything there are tradeoffs.

“Views may and probably will decrease your performance.”

As I have written in the past, I am a believer in making tradeoffs, as long as you understand what is on the table. More than likely someone will skim past this paragraph and make a comment that you should never use a view because of the performance hit. I disagree. You should use every tool in your toolbox, but when they make sense. You don’t use a hammer to put a screw into a wall, just as you wouldn’t use a view when you really need a heap / memory table. The flip side is the development usability for your applications. When it makes sense to save time, effort, and energy over the performance hit that you might take, take that choice. Development isn’t all about the performance of your applications, as there are other considerations such as support, time to market, and overall value of your time.

The tools that I am working with in this tutorial are pretty standard. I am using phpMyAdmin for the database interaction for explanation purposes. I will also be using very rudimentary table structures, strictly for ease of explanation. I don’t expect that these table structures would ever be used in a production environment, as I am merely using them for illustration.

One further note. There is no right or wrong way to name a view. However, I do name my views with the syntax of view_*primary_table*_*what_the_view_is_used_for* unless I am working for backwards compatibility changes. So, if I was creating a view for statistical reporting purposes on my salesforce table, my view name would be: view_salesforce_statistical_report. That can be rather long and you only have 64 characters to work with, so keep that in mind. It works for me, and my style, it might not work for you.

“I am not going to say that views will change your life, but I will tell you that they will make the job of database interaction a little easier to work with. They will make your job a little easier when you make major version changes in your interaction layer. They will also make some difficult tasks such as dynamic reporting a little more efficient and a little easier to work with.”


Definitions: How to Define a View

As I stated, a view is just a query. There are some slight configurations that we need to make when creating a view, so let’s discuss that first. In phpMyAdmin, in the “browse” table page, you will see a link called “Create View”.

Create View Link

If you click on that link you should see something that looks like this:

Create View Page

This, my friends, is where the magic happens. There isn’t much to explain on the page, but let’s take a quick look at the definitions that we need to understand to create a view.

First, there is “Create View” followed by “OR REPLACE”. If you click the OR REPLACE it will do exactly as you think, which is overwrite an existing view. Column names is the name of the columns in your table. Each is seperated by a comma, so it might look like first_name, second_name, etc. AS is the query.

There are two more items to explain, but the concepts are not hard. ALGORITHM has the selections of undefined, merge, and temp table. If you select “Merge” when there is a one to one relationship it will combine the incoming query with the view. Temp table is less efficient, but when you are not using a one to one relationship, such as a aggregation function like SUM() or you are using certain keywords like GROUP BY or HAVING or UNION, you have to use the temp table algorithm. That said, you can do like I do, and leave the algorithm as “undefined” and MySQL will select the best algorithm to use.

Finally, we have CASCADED CHECK OPTION and LOCAL CHECK options. The check options tell MySQL to validate the view definition if there is a condition on the query, like WHERE. If the WHERE clause excludes data, it will prevent updates or insertion of those rows where it should be excluded. The LOCAL CHECK deals with just the view you are defining, where CASCADED CHECK is for views that you have defined from other views. It will cascade the check for those as well.

That’s a view in a nutshell. Let’s take a look at some use cases to see them in action and where they may help your development efforts.


Backward Compatibility: For the Procrastinator

I have had it happen more times than I would care to mention when I design a single use table which I never think will need to be normalized further inevitably does. Let’s take the example that showed before with a few more records.

Not Normalized

Obviously, my normalization skills leave something to be desired in this example. What I probably should have done when I first created this table, was have a seperate table for addresses, and then just call an address_id in my sales force table. The problem is, once I move to a database change, I have to run back through my logical interaction layer and make numerous query changes. Instead of doing that much work, why not let a view come to the rescue.

First, let’s make the change to my table structure. I copy my table structure and data to my new table, addresses and make the table sane such as adding address_id and removing the unneeded structure:

Create Address Table
Address Table

Then I just need to delete the offending columns and add my address_id back to my sales table.

Sales Table

This is a pretty common change that you make on a semi-regular basis, although rather simplistic in nature. You figure out that you can normalize something because of a new feature. In this case, we can reuse our addresses for customers, or for other employees, or for whatever we might store addresses. This work isn’t that difficult, but depending on your query reuse, finding all of the places that you call our old sales_force table might be a much larger change in scope. In comes a view.

Instead of going back through our code right now, and instead wait for a normal release cycle, we can create a view to keep our old functionality intact. I changed the name of our sales_force table to sales_force_normalized:

Change My Table Name

Now we can create our view to maintain backwards compatibility:

Create My View

And we have our backwards compatibility with just the extra work of creating one query that sits in MySQL:

Backwards

Even when I enter a new sales person, my view will reflect the change:

Add Jin

And, presto:

Works!

About two minutes of work to maintain our backwards compatibility to our previous data structure. There are drawbacks to this method, in that you can not define an index against your view which is important when you are cascading views. In addition, you will still need to change your queries for INSERT, DELETE and UPDATE, but this will save you some work. Your performance could drop a bit, but as a stop gap, there is no easier way to make a change to your data structure to ease your code base into that change. Your queries in your logic layer will be untouched because as far as they know, they are looking at the original table.


Complex Queries: Making the Hard Bearable

Now that we have our proof of concept under our belts, let’s look at another use. I created another table to capture the sales data from my salesforce table and filled it with some random information. It looks like this:

It’s an extremely simplified table to capture the sales of the salesforce for illustration. There are always things that we want to extract for measurement on a table like this. I probably want to know the total sales. I probably would want to know the total sales by person. I also might want to know the rank of the sales performance. I could write queries in my database logic to perform each of these when I need them, or I could simply write a view to grab the data as needed. Since this is a tutorial about views, I guess the choice is pretty simple at this point which tactic to take.

Let’s start by evaluating the total sales, along with some other pertinent information:

Which gives us a view of:

I also included the query time on this one, as looking at 200 records, this is lightening fast, but performance will vary. Notice that I am not using the CHECK functions because I am not discriminating the information in a WHERE clause. Now that we have this information neatly packaged, it’s just a matter of building our reporting mechanism in our logic.

Getting this information isn’t that hard. Let’s take this just a step further and use a GROUP BY function and a join function against the salesforce. Again, I am using simplified queries to illustrate. In this case, we want to get the same information that we had from total sales, but this time broken down by our individual sales person.

Which gives us a view of:

Again, very simple in the end to get these values out of your database. Let’s take a look at one more example, which will combine the two views. I want to compare the totals against the individual, and so we will create a view of two views:

Which gives us a view of:


Conclusion

One other benefit of views is they do provide a further level of security to your applications. You are not exposing your table structure to your application. Instead, you’re exposing something that doesn’t really exist, except as a pseudo table. I wouldn’t call a view a best practice and use them primarily for writing secure applications, but I would look at it as an added benefit.

I use views in a limited fashion. Where I use views are as demonstrated above, particularly in the reporting mechanisms in my applications. Writing a query to perform the heavy lifting for me is much easier than writing the logic around more difficult queries. I do take a bit of a hit on my performance from time to time, which I tend to overcome by optimizing the original data structure. I’ve yet to have one be a show stopper in terms of performance, but the day is young. Thanks so much for reading.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.kimsebeniokumuyor.com Ege

    You should never use views, when you can achieve the exact with stored procedures. And that also adds an additional layer on top of the model, which is usually handy.

    • DED

      The crux of your point is “when you can achieve the exact same thing with stored procedures.” The problem being that in a web environment it can be extremely difficult to determine when a stored procedure may need to change or what those changes may impact inside and outside the DBMS. It seems you glossed over that aspect of using stored procedures.

      • http://www.kimsebeniokumuyor.com Ege

        Yes, making changes becomes somewhat a hassle for procedures but querying a view, which means that you actually query the results of a query is something that will really hit your application when you need to scale. Also, assuming your application is properly tested, you can easily see the impact of changing a procedure. The only thing I’d worry about using procedures is that you expose some part of your model logic to anyone who can access the database. That wouldn’t be a problem for most of the apps but anyway…

    • http://wyome.com John Cox

      I hear ya, but I believe there are few use cases, such as creating views of views where you are not going to be able to achieve the same result. For instance, joining multiple views together, or the case of backwards compatibility above where you can use a pseudo table after the original table has been dropped, etc. I’m sure there are a few more from more creative folks than myself.

      An advantage a view has is to hide the table structure from the application as well. You can’t directly update, delete or create to a view which might have some advantages to a larger application or depending on a team dynamic.

      I do agree with you to use the right tools in the right place, but not with the “never” aspect, but that’s just me;)

  • http://www.jordanwalker.net Jordan Walker

    Agree with Ege, stored procedures are the way to go!

  • http://www.markdijkstra.eu Mark Dijkstra

    Well i didn’t know this so thanks!! This can be off help for me.

    • http://wyome.com John Cox

      Just remember there is a cost, albeit small with a well indexed db, in using a view. It’s a good tool to use, but like any overuse probably isn’t advised:)

  • Michael

    As I use really small databases a lot, this will definitely make some things easier.

    thx a lot

    • http://wyome.com John Cox

      I personally think they come in handy, glad you picked something up from the topic:)

  • http://brianswebdesign.com Brian Temecula

    You obviously like LOST. I got netflix about a month ago, and I’m on season 3. Pretty cool show.

    • John Cox

      Loved it, and it was easier than working in “The Wire” references;)

  • http://www.wwebz,com wwebz

    Very good article. Actually this all database thing is like alien’s language :). Now i need to learn this.

    • http://wyome.com John Cox

      The nice thing about learning databases is that once you learn, it’s pretty easy to move from platform to platform. I think it’s easier to pick up new languages as well, because you understand how the data is being stored, and at that point it’s simple manipulation:)

      I am glad you enjoyed it.

  • http://freecss.info CSS Tutorials

    Great tut as usual. Pics help a lot.

    • http://wyome.com John Cox

      Glad it helped a bit:)

  • http://www.gamecardsdirect.nl Tom

    Thanx, this was exactly what i was looking for!

  • Adam

    Great article!

  • http://www.intutorials.com Chris

    Great article, but in all my years of using MySQL (and MSSQL for that matter) I cannot remember ever needing a view to achieve my goal.

    • http://wyome.com John Cox

      I’ve never used them in MSSQL either, because I am generally writing CF with MSSQL, and I prefer to use query of queries at that point which achieve basically the same thing without the overhead in the DB.

      That said, I have used them in MySQL / PHP for reporting (which is generally when I use the QoQs) because I like to combine several views together. There might be a better way to do it (as there usually is), but I like them probably because of working with CF for a few years;)

    • Markus

      Well ther’s a really obvious use case for a view. Let’s think about a query you use a lot in your application at different locations or even worse in multiple applications that access the same database. Some of those applications might not be even written in the same programming language or by the same contractor. So when this query needs to be changed you’re in trouble. If you used a view then you can just change the view in the DBMS and all appplications immediately use the same new query (well as long as you don’t change the field declaration).

    • http://createmy.com.au Dale Hurley

      After years of working with databases I do not know why I never looked into this for MySQL. It is so logical. To me I can see a lot of possibilities in reporting on data. I don’t think I will use views in most cases but when there is a report this is going to be great.

  • http://harikt.com Hari K T

    Great . I loved the simplicity .

  • momay

    this tutorial is great.

    i was wondering if anyone can help me with my problem about joining a superclass with its subclasses. i was particularly thinking if views can be of help to this…

  • http://www.tenaxtechnologies.com complex web development

    Thanks for really good tutorial!

  • King

    Congratulation on the tutorial. Great job. It’s easy to pick up as I just started to learn SQL. Mind if I ask to further my understanding.

    Is the function of query builder and view identical?

    Referring to your jointed view example (your last image). Let said that values in the pseudo table represent the end year result. And there is a yearly performance column in the main table. Can these values in the last two columns add to the main table as a constant value?

  • omprakash

    Great tutorial But i want to ask here one thing we are building views using SELECT queries from another TABLES. When i am trying to access any data from VIEWS then what will happen. I am thinking first QUERY is going to execute which need to build VIEW and then our next QUERY is executed to fetch data from VIEW. Now my question is i want to access my data fast how it is possible if my create VIEW QUERY contains more than two tables. Please reply..

  • Joe

    Hi, i’m new to databases and sql and i’ve been searching the web for an answer and understand why there is a. s. os. o. before the name of the table or column name when passing a query, like this:

    a.sales_id
    s.extensions
    os.order_id
    o.status_id

    i’ve seen it here again but i can’t find a place that explains it, i’m currently learning databases and i’m a little confused by this, could anyone tell me where i can find an answer or explain it to me please.

    Cheers!

    • http://twitter.com/theyanasela † Dyan Pauline †

      It is to create indexes for each column of each table.It’s used instead or typing the tablename.column name which is much easier.

  • Alex

    What are Check functions?

    Notice that I am not using the CHECK functions because I am not discriminating the information in a WHERE clause.

  • Francisc

    Really enjoyed the tone of this article.
    Good information too.
    Thanks, John.

  • http://dirtyhandsphp.blogspot.com/ Shiv

    Awesome man :) Keep it up!!!!!!