How to give table an alternative name in MySQL? - 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 ;

Related

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

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

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.

Normalised tables, SQL Joins and Views

I am creating a booking application and have normalised the database as much as is possible. My question is the following, should I create Views in the database that combine the tables again before I do selective selects on the combined view in the WHERE clause or is it better to filter the tables with selects before joining them in a view?
EDIT: Included example.
The first scenario creates the combined view first, and then performs the SELECT on the combined view (this view may have thousands of records):
CREATE VIEW appc as
SELECT * FROM appointment
LEFT OUTER JOIN chair
ON appointment.chair_idchair = chair.idchair
SELECT * FROM appc
WHERE chair_idchair = 1;
The second scenario will first filter the table in the left of the join and then create a view based on the filtered table, then the join will be made using this much smaller view:
CREATE VIEW appf as
SELECT * FROM appointment
WHERE chair_idchair = 1;
SELECT * FROM appf
LEFT OUTER JOIN chair
ON appf.chair_idchair = chair.idchair
It makes little difference to MySQL. MySQL (unlike some other RDBMS brands) does not store anything in the view itself. Think of a MySQL view more like a macro. In most cases, querying the view is exactly like executing the query you defined as the view.
Applying subsequent conditions in the WHERE clause when querying the view is combined pretty transparently with the view's query, as if you had written the full query and given it one more condition.
Exception: you can optionally create the view with ALGORITHM=TEMPTABLE, to force it to store the results of the view in a temp table, and then apply extra conditions you specified in your query. In this case, it would be better to build the conditions into the view's query, to reduce the size of the resulting temp table.
See http://dev.mysql.com/doc/refman/5.6/en/view-algorithms.html for more details.
As a general rule, the optimizer is pretty smart, and can see right through the views when constructing a query plan. If you try to "help" the optimizer by pre-selecting some data, you may be hiding information from the optimizer that would have allowed it to create a smarter, more-optimal plan.

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.

Performance issues of mysql query as compared to oracle query

I have created a complex view which gives me output within a second on Oracle 10g DBMS.. but the same view takes 2,3 minutes on MYSQL DBMS.. I have created indexes on all the fields which are included in the view definition and also increased the query_cache_size but still failed to get answer in less time. My query is given below
select * from results where beltno<1000;
And my view is:
create view results as select person_biodata.*,current_rank.*,current_posting.* from person_biodata,current_rank,current_posting where person_biodata.belt_no=current_rank.belt_no and person_biodata.belt_no=current_posting.belt_no ;
The current_posting view is defined as follows:
select p.belt_no belt_no,ps.ps_name police_station,pl.pl_name posting_as,p.st_date from p_posting p,post_list pl,police_station ps where p.ps_id=ps.ps_id and p.pl_id=pl.pl_id and (p.belt_no,p.st_date) IN(select belt_no,max(st_date) from p_posting group by belt_no);
The current_rank view is defined as follows:
select p.belt_no belt_no,r.r_name from p_rank p,rank r where p.r_id=r.r_id and (p.belt_no,p.st_date) IN (select belt_no,max(st_date) from p_rank group by belt_no)
Some versions of MySQL have a particular problem with in and subqueries, which you have in this view:
select p.belt_no belt_no,ps.ps_name police_station,pl.pl_name posting_as,p.st_date
from p_posting p,post_list pl,police_station ps
where p.ps_id=ps.ps_id and p.pl_id=pl.pl_id and
(p.belt_no,p.st_date) IN(select belt_no,max(st_date) from p_posting group by belt_no)
Try changing that to:
where exists (select 1
from posting
group by belt_no
having belt_no = p.belt_no and p.st_date = max(st_date)
)
There may be other issues, of course. At the very least, you could format your queries so they are readable and use ANSI standard join syntax. Being able to read the queries would be the first step to improving their performance. Then you should use explain in MySQL to see what the query plans are like.
Muhammad Jawad it's so simple. you have already created indexes on table that allow database application to find data fast, but if you change/update the (indexes tables) table (e.g: inserst,update,delete) then it take more time that of which have no indexes applied on table because the indexes also need updation so each index will be updated that take too much time. So you should apply indexes on columns or tables that we use it only for search purposes only. hope this will help u. thank u.