What is MySQL View for? - mysql

MySQL Documentation explains how to create a view. However it doesn't explain why should I make a MySQL View in the first place.
Thus, my question is, what is MySQL View? What is it for? At what circumstances should I make or not make one?
Quoting the documentation
The view definition is “frozen” at creation time and is not affected by subsequent changes to the definitions of the underlying tables.
I don't see how creating a view would be beneficial, so please, enlighten me.

View the data without storing the data into the object.
Restrict the view of a table i.e. can hide some of columns in the tables.
Join two or more tables and show it as one object to user.
Restrict the access of a table so that nobody can insert the rows into the table.

Where I work, we use the views as big painful querys that we need many times, we decided to create views for them instead of doing a manual query and when we need to access the information
SELECT * FROM view WHERE (anything)

Related

How do I disable a column in a MySQL table?

I'm updating an old MySQL database and find that several columns in various tables are not needed. But rather than just remove the columns, I'd like to disable them temporarily so I can test the code and see how many things break before I decide to complete remove the column. How can I tell the server to throw an error if a particular column is accessed?
You may rename table oldname to newname and create view using oldname. that view look like column removed table. if have some problem. you just change name table and view.
You might want to consider using a view for this. As an example I created this fiddle : http://sqlfiddle.com/#!2/a8947/2
Take a look at the two queries. One selects the table with the column you aren't sure you need (which I called "legacyData"). The other selects the view. You can see that in the view, the column "legacyData" no longer exists.
I don't think this will work if you are writing from the table, but if you are reading from the table a view is a viable option.
The steps you'd want to take in production to try it out would be:
Rename your table ('myTable' to 'myTableDontUse', for example)
Create the view based on the newly renamed table
When you name the view, name it the table's original name (myTable in this example)
By doing that, you've replaced your table with a view. This approach would allow you to see if applications are accessing the legacyData field of that table. If not, you can remove the view, rename your table, and drop the column in question.
Performance typically is not great with a view especially if you have a lot of data, so be careful of that. In a similar situation, I started out with a view but due to performance reasons (table had 2M+ rows), we changed to a normal table that was instead populated via triggers.

MySql - Select * from 2 tables, but Prefix Table Names in the Resultset?

I'd like to select * from 2 tables, but have each table's column name be prefixed with a string, to avoid duplicate column name collissions.
For example, I'd like to have a view like so:
CREATE VIEW view_user_info as (
SELECT
u.*,
ux.*
FROM
user u,
user_ex ux
);
where the results all had each column prefixed with the name of the table:
e.g.
user_ID
user_EMAIL
user_ex_ID
user_ex_TITLE
user_ex_SIN
etc.
I've put a sql fiddle here that has the concept, but not the correct syntax of course (if it's even possible).
I'm using MySql, but would welcome generic solutions if they exist!
EDIT: I am aware that I could alias each of the fields, as mentioned in one of the comments. That's what I'm currently doing, but I find at the start of a project I keep having to sync up my tables and views as they change. I like the views to have everything in them from each table, and then I manually select out what I need. Kind of a lazy approach, but this would allow me to iterate quicker, and only optimize when it's needed.
I find at the start of a project I keep having to sync up my tables and views as they change.
Since the thing you're trying to do is not really supported by standard SQL, and you keep modifying database structures in development, I wonder if your best approach would be to write a little script that recreates that SELECT statement for you. Maybe wrap it in a method call in the development language of your choice?
Essentially you'd need to query INFORMATION_SCHEMA for the tables and columns of interest, probably via a join, and write the results out in SQL style.
Then just run the script every time you make database structural changes that are important to you, and watch your code magically keep up.

How to enable users only to view certain rows in a table

I currently have two tables. One is accounts and one is tbl_units_info. My boss wants me to make it so that accounts are restricted from reading certain rows in a table. Frankly, I think my boss has no idea what he is talking about, but I'm hoping someone here can prove me wrong.
For example, accountname krikara can only view the entries of the tbl_units_info table where the TBID column is 0909.
Is this even possible? To make krikara only able to view the rows in that table where column TBID = 0909?
It can not be implemented plainly on DBMS level since SELECT privilege has table level. You can not restrict rows reading. And this is good, I think - because data could be changed, so in general there is no solid condition for rows restriction (and, therefore, there could not be valid implementation for that on DBMS level).
You can, however, use VIEW - but it is a middlepoint, not common solution (I still not think it will help with tracking rows changes, but may be I'm wrong due to your application logic)
You can try to implement it in your application, but it still has problem I've described above: in table, data is changing. You'll probably have troubles with tracking all changes. I think you can separate your rows on two (several) tables and then build your permissions model. But - if some basically similar entities must have different permissions - probably you should reconsider application security model?
You could solve it by giving accounts just the reading rights to a view instead of the whole table.
CREATE VIEW `tbl_units_info_krikara` AS
SELECT * FROM `tbl_units_ino` WHERE `TBID`='0909';
And then assign the respective rights to your user.
MySQL CREATE VIEW documentation

Regex for SQL string to allow SELECT queries on variable named tables only?

The table names are variable, but what is certain is that SELECT only is allowed and certain tables are excluded (ie Users, Log). I'm making a reporting form where a user can just enter sql queries to make template reports.
SELECT 'field1' As 'foo', 'field2' as 'bar'.. 'fieldn'
FROM 'table1',..'tablen'
JOIN ... ON ...
WHERE CONDITION
Although I'm thinking I can have the table names in a html select list of existing tables.
Also make a user reporter_appname#localhost with SELECT access only to all tables except Users and Log? In that case I won't need to bother with a regex check of the query?
(This would be in PHP)
(Ideally I just wanted a single textarea where the admin can just type their query, my report function would then take the output and present it nicely etc.)
I suggest you re-think your design.
Identifying valid select statements (and excluding all other statements) is basically impossible without completely parsing SQL. A regex is not going to be up to the task.
Even if you allow only select statements, users could perform denial-of-service attacks on your database. It is very easy to create select statements that run forever (we've all done it). A malicious user could crash your site in a hurry. And even well-intentioned users might do this by accident.
It would be much better to give the users more limited options for creating reports. Let them select certain tables and columns from a list, and create the appropriate query for them.
There is probably free MySQL reporting software out there that could serve as a good starting point, though I don't have any experience with this myself.
I think that you should rethink the design of your application.
The Users and Log tables should be on one database and the tables with the data for the reports should be on another database.
If you have them all in one database already just create another database, link them and then create synonyms from one database to another only for the tables that the user can access via his queries.
The user will run his queries on the database you have just created and he will be limited to those tables that have synonyms on it.
I do not know if this would be the best option because your description of the case is relatively vague but based on the information I have this could be a solution.

mysql don't return results if not from statement but from INDEX table or something

I think my question was a little confusing.....It confused me :)
Working on a media site as a take-over project and it has a custom CMS. The client wants the ability to activate/deactivate media....sort of like Wordpress's publish/unpublish feature.
Instead of digging through all the code looking for mysql queries (which I'm not opposed to), I was wondering if you can add a sort of INDEX to a table that won't let it return result rows if that rows "active" column = let's say 0.
Just trying to be lazy and learn something at the same time, heh.
I don't need examples of queries to make it happen, btw.
What you describe is called a "view". Here is a page describing how to create them in MySQL: http://dev.mysql.com/doc/refman/5.0/en/create-view.html. However, in most cases you will still have to alter your code to use the view instead of the table.
You can consider create a view (which contains active record only)
AND swap the view name to actual table name instead, so you can achieve the negative filtering without changing any of your source code.