Selecting all columns from a view table and adding additional columns [duplicate] - mysql

When you create a view with
CREATE VIEW view1 AS SELECT * FROM table1
mysql changes this internally to
CREATE VIEW view1 AS SELECT f1, f2, f3 FROM table1
If you add a new column f4 to table1, view1 still has only the first 3 columns. You have to recreate your view. This is annoying, if you have a lot of views.
Is there a way to make mysql to save SELECT * in the view declaration so it always selects all the fields no matter if the table has changed?

MySql has a right behaviour.
When you create a view as SELECT * FROM table1, MySql changes your code with a full list of fields.
When you change your table structure, the view must be changed by user.
If exists this automatic behaviour you can create an issue of performance when you use a view.
Suppose you add 50 fields, and you use your view in a form, you can change the data load from 3 to 53 fields. No good.
So this behaviour is correct.

Long story short, no. This is how MySQL handles views internally.
Pro tip: don't use views. It's a poor man's way of hiding unnecessary complexity behind another complexity. It's way better to simply do plain query, MySQL performs better that way.

A MySql View does not use for return a complete definition of a table it's basic use to return a part of the tables with a specification or marge data.
Views would not be of much use without it.The principle also applies if you select from a view that selects from the table if the view selects from the table in a subquery and the view is evaluated using the merge algorithm.View processing is not optimized.
You can see this blog to know what is right with a view to MySql.View Restrictions

Related

How to give table an alternative name in MySQL?

I want to use a table that would be accessible under two names (something like e-mail address alias) i.e. I want queries:
select * from my_table_name
and
select * from my_alt_table_name
return records from the same table.
I know I can use a view and then run query on view, but wouldn't it be less efficient?
I know I can use a view and then run query on view, but wouldn't it be less efficient?
If the view is strictly SELECT * FROM table, without any additions (WHERE and so on), then there is no difference does you use the table or the view as an alias.
See small DEMO.
See SHOW WARNING outputs - they claims that the server is smart enough for to understand that it may/must use the table itself.
See EXPLAIN outputs - they claims that the server is smart enough for to understand that it may/must use the index which is present in the table structure.
expanded DEMO fiddle - analyse it by itself.
Also study CREATE VIEW Statement, ALGORITHM clause, and View Processing Algorithms. Try to add ALGORITHM = TEMPTABLE to DEMO and investigate the changes.
You can't have a table with multiple names, so yeah, just use views. There will be no impact on performance during the runtime, however during the compilation of the query, there will be just a small delay time for the compilation of the view to be transformed into a table in memory which is absolutely negligible
CREATE VIEW table_name_alias AS SELECT * FROM table_name;
SELECT * FROM table_name_alias;
Creating a view would look like this
CREATE VIEW my_alt_table_name AS SELECT * FROM my_table_name;
and next time you can use it like this
SELECT * FROM my_alt_table_name ;

What is MySQL View for?

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)

Determine the original table of a column in a view

Is it possible to find the name of the table for which a column in a MySQL view belongs?
If a view was constructed as
CREATE VIEW alpha_view AS
SELECT alpha.col1, alpha.col2, beta.col2 FROM alpha
INNER JOIN beta
ON alpha.col1=beta.col1;
then when I edit, I want to only affect alpha.col1 and alpha.col2 as beta.col2 is derived from another table.
I assumed the easiest way of knowing whether it's editable or not comes from knowing if the original table matches the view's FROM clause.
Is this even possible, or should I just make a list of editable columns for my parsing script?
Yes, it is possible. Just use aliasing (via AS keyword) to give different name for result column.
CREATE VIEW alpha_view AS
SELECT alpha.col1 AS a_col1, alpha.col2 AS a_col2, beta.col2 AS b_col2 FROM alpha
INNER JOIN beta
ON alpha.col1=beta.col1;

Is it safe to use select * in views?

I've grown quite fond of the usefulness of CREATE VIEW. It for instance allows me to have global and specific values through COALESCE(post.publish, profile.publish) so that if publish is NULL, the global value gets fetched instead.
The part I'm a bit curious about from both perfomance and logical perspective, is how I should use this alongside the existing table. Lets say I have a table:
CREATE TABLE post (
id INT,
profile_id INT,
name VARCHAR,
publish ENUM('TRUE', 'FALSE') NULL
)
Would a CREATE VIEW be best to run like:
CREATE VIEW post_info AS
SELECT post.*, COALESCE(post.publish, profile.publish) AS publish
FROM post
INNER JOIN profile
ON post.profile_id = profile.id
And only use post_info in SELECT cases, or:
CREATE VIEW post_info AS
SELECT post.id, COALESCE(post.publish, profile.publish) AS publish
FROM post
INNER JOIN profile
ON post.profile_id = profile.id
And JOIN post_info with post in SELECT when extra values are needed?
Please share your insights and thoughs regarding this. I would like to hear your input to positives and drawbacks of each solution. Can also be one I haven't mentioned.
It really depends on how you will use the views. It should be worth mentioning that there are two methods MySQL can process a query that refers to a view, and the method used depends on the view declaration's ALGORITHM clause.
For the lack of a better phrasing, I will reproduce the manual:
For [ALGORITHM =] MERGE, the text of a statement that refers to the view and the
view definition are merged such that parts of the view definition
replace corresponding parts of the statement.
For TEMPTABLE, the results from the view are retrieved into a
temporary table, which then is used to execute the statement.
For UNDEFINED, MySQL chooses which algorithm to use.
The MERGE algorithm usually allows faster processing of the final query, however there are many cases where MySQL is unable to use it (see the linked manual page for more details).
So the answer is: if your view is not defined with ALGORITHM = TEMPTABLE and if the wrapping query does not prevent the use of the MERGE algorithm, the version with SELECT *, and without an extra JOIN, is better.
Otherwise, if MERGE is not used, the second solution could be better.
As a side note, to adress the use case you mention, a better option would be to have your application layer fill the post.publish with the value in profile.publish at insertion time, and get rid of the JOIN as well as the view. Alternatively, the same effect can be achieved by placing a suitable trigger on the table.

Advantage of using Views in MySQL

I've learned that views can be used to create custom "table views" (so to say) that aggregate related data from multiple tables.
My question is: what are the advantages of views? Specifically, let's say I have two tables:
event | eid, typeid, name
eventtype | typeid, max_team_members
Now I create a view:
eventdetails | event.eid, event.name, eventtype.max_team_members
| where event.typeid=eventtype.typeid
Now if I want to maximum number of members allowed in a team for some event, I could:
use the view
do a join query (or maybe a stored procedure).
What would be my advantages/disadvantages in each method?
Another query: if data in table events and eventtypes gets updated, is there any overhead involved in updating the data in the view (considering it caches resultant data)?
A view is not stored separately: when you query a view, the view is replaced with the definition of that view. So and changes to the data in the tables will show up immediately via the view.
In addition to the security feature pointed out earlier:
If you're writing a large number of queries that would perform that join, it factors out that SQL code. Like doing some operations in a function used in several places, it can make your code easier to read/write/debug.
It would also allow you to change how the join is performed in the future in one place. Perhaps a 1-to-many relationship could become a many-to-many relationship, introducing an extra table in the join. Or you may decide to denormalize and include all of the eventtype fields in each event record so that you don't have to join each time (trading space for query execution time).
You could further split tables later, changing it to a 3-way join, and other queries using the view wouldn't have to be rewritten.
You could add new columns to the table(s) and change the view to leave out the new columns so that some older queries using "select *" don't break when you change the table definitions.
You can restrict users to the view instead of the underlying table(s), thereby enhancing security.
Advantages of SQL Views
1). You can save a complex query(a query with join multiple tables) as view to reuse it in simple manners.
In other words, you can change your multi-line query into single-line query.
2). You can hide sensitive data by converting your query into view with new name and can give the access only required columns instead of giving the access of actual table.