Matching two columns from a database - mysql

I'm gonna implement a new design / website structure for a customer, but I have a little problem. Since the URLs I've created are a bit different, I'm anticipating a problem with the SEO rankings due to the bunch of broken URLs. My idea is to match the existing URLs (from the old site) with the new ones I've created.
The problem I've stumbled upon is the following:
The old URLs are like http://www.example.com/category/numeric_id-item-name_item_code.html and the new URLs are likehttp://www.example.com/item_name-item_code.
In MySQL I created a new database containing on the first column the item_name and item_code from the old website and a second column the same info from the new database.
The idea is as it follows:
Example: Let's say we have an item named spring leaf with the code sl34. The old URL would be something like http://www.example.com/springs/53-spring-leaf-sl34.html.
For matching this URL there are 3 possibilities:
If the product is in the new website http://www.example.com/spring-leaf-sl34
In case they modified the name http://www.example.com/iron-spring-leaf-sl34
In case the product is not in the new website: http://www.example.com/springs
I need help on creating these matches.
Thank you.

So, apparently, I've found some kind of quick fix:
CREATE
VIEW `database`.`url_view`
AS
(SELECT old_table.old_url, new_table.new_url FROM old_table LEFT JOIN new_table ON old_table.product_code=new_table.product_code);
This will associate the old URLs with the new ones, and, if an old URL (product) is no longer available it will insert a (NULL) entry.

Related

About Slugs Creation in codeigniter

Hello Every Every One here me.
Actually me trying one thing from many days it about URL means me want friendly Url in my site Besides showing id etc there.Like (www.abc.com/this-is-me-from-php-show-test) in replacement of this (www.abc.com/controller_name/function/23) kindly help me as soon as possibly by badly i have no written code for you guys.just suggest me any site or tutorial about it.both suggestions appreciated dynamic slugs or static.Thanks
Assuming you have a table called projects and currently it is identified by the id field e.g. localhost/projects/get/123 then you should create another column in that table for slugs where you put the name-of-the-project. Then in your get($slug) function instead of querying the id field for the specific project query the slug field.
You can use a 3rd party library to generate slugs: https://github.com/ericbarnes/CodeIgniter-Slug-Library/blob/master/Slug.php
Then just write a script to populate all of the slug fields and it might be a good idea to test if the $slug field is an integer indicated a legacy id for current SEO purposes (to prevent broken links).

replacing multiple table information in mysql

I've recently been given the task of maintaining a sports team's website and have encountered a problem which I cannot find the answer.
It uses Nucleus CMS which is fine and I'm used to it, unfortunately, the domain name has changed and all links and files within the site stored in the mysql database are now out of date and not the correct one.
I am able to manually alter each item using the admin panel of the CMS, but with several thousand posts, that task is daunting.
Is there a way I can do a "replace" domain1.com to domain2.com in the item table in one process through the mysql database?
Forgive me if I'm not using the correct terminology.
Try this:
UPDATE tbl SET domain_name = 'domain2.com' WHERE domain_name = 'domain1.com';

MySQL 5.5 Database design. Problem with friendly URLs approach

I have a maybe stupid question but I need to ask it :-)
My Friendly URL (furl) database design approach is fairly summarized in the following diagram (InnoDB at MySQL 5.5 used)
Each item will generate as many furls as languages available on the website. The furl_redirect table represents the controller path for each item. I show you an example:
item.id = 1000
item.title = 'Example title'
furl_redirect = 'item/1000'
furl.url = 'en/example-title-1000'
furl.url = 'es/example-title-1000'
furl.url = 'it/example-title-1000'
When you insert a new item, its furl_redirect and furls must be also inserted. The problem appears becouse of the (necessary) unique constraint in the furl table. As you see above, in order to get unique urls, I use the title of the item (it is not necessarily unique) + the id to create the unique url. That means the order of inserting rows should be as follow:
1. Insert item -- (and get the id of the new item inserted) ERROR!! furl_redirect_id must not be null!!
2. Insert furl_redirect -- (need the item id to create de path)
3. Insert furl -- (need the item id to create de url)
I would like an elegant solution to this problem, but I can not get it!
Is there a way of getting the next AutoIncrement value on an InnoDB Table?, and is it recommended to use it?
Can you think of another way to ensure the uniqueness of the friendly urls that is independent of the items' id? Am I missing something crucial?
Any solution is welcome!
Thanks!
You can get an auto-increment in InnoDB, see here. Whether you should use it or not depends on what kind of throughput you need and can achieve. Any auto-increment/identity type column, when used as a primary key, can create a "hot spot" which can limit performance.
Another option would be to use an alphanumeric ID, like bit.ly or other URL shorteners. The advantage of these is that you can have short IDs that use base 36 (a-z+0-9) instead of base 10. Why is this important? Because you can use a random number generator to pick a number out of a fairly big domain - 6 characters gets you 2 billion combinations. You convert the number to base 36, and then check to see if you already have this number assigned. If not, you have your new ID and off you go, otherwise generate a new random number. This helps to avoid hotspots if that turns out to be necessary for your system. Auto-increment is easier and I'd try that first to see if it works under the loads that you're anticipating.
You could also use the base 36 ID and the auto-increment together so that your friendly URLs are shorter, which is often the point.
You might consider another ways to deal with your project.
At first, you are using "en/" "de/" etc, for changing language. May I ask how does it work in script? If you have different folders for different languages your script and users must suffer a lot. Try to use gettext or any other localisation method (depends on size of your project).
About the friendly url's. My favorite method is to have only one extra column in item's table. For example:
Table picture
id, path, title, alias, created
Values:
1, uploads/pics/mypicture.jpg, Great holidays, great-holidays, 2011-11-11 11:11:11
2, uploads/pics/anotherpic.jpg, Great holidays, great-holidays-1, 2011-12-12 12:12:12
Now in the script, while inserting the item, create alias from title, check if the alias exists already and if does, you can add id, random number, or count (depending on how many same titles u have already).
After you store the alais like this its very simple. User try to access
http://www.mywebsite.com/picture/great-holidays
So in your script you just see that user want to see picture, and picture with alias great-holidays. Find it in DB and show it.

Choose a database table to join with, using a field value

The website I'm building has a table which stores all the information of uploaded images on the site. These uploaded images can come from different resources such as a guestbook, news section or an item from an agenda.
Ofcourse I want the image to inherit the rights of the resource it is part of. For example: if user A isn't allowed to view the guestbook I don't want him to be able to view an image posted on the guestbook by going to image/view/id/12 (which would be the image request used it in the guestbook).
What I have now is that the system remembers the resources used (in this case the guestbook) the image-id is coupled to the resource-id. However I don't know to which guestbook post the image is connected (I do ofcourse know it the other way around).
Is there a way in SQL to connect one table field to a field in another table, where which table I connect to can vary based on one of the first table's field values?
In my case I would like to connect an image to a resource this could be a guestbook post in the table gb_posts or an agenda item in the table agenda_items.
Or is this all a stupid way of solving the problem and should I not use one table for the uploaded images but keep the image attached to the resource (as a column in the table for example)? It sounds like using one table is at least a lot slower in use (but I would have a great overview of all the images in one place).
I hope you guys can help me out.
EDIT: extra explanation: db model
I will try to explain how it all works the best I can.
First of all: I use Zend Framework, and therefor I also use Zend_Acl for working with priveleges.
My DB structure:
- Users are connected to roles (directly or by being connected to a group that is connected to a role)
- There is a table resources containing all the resources which is connected to priveleges. For example: guestbook is a resource, view or edit are the priveleges. Next to the controllers/actions there can also be other resources in this table such as a category within the agenda or a file location.
- roles are connected to a privelege
When for example the guestbook is requested for viewing I can check if the user is allowed to.
In short something like:
users -> roles -> priveleges <- resources
When a user adds a guestbook post with an image, the used resources (in this case guestbook is saved):
guestbook_posts -> images -> resources
I hope this explains my DB model for a bit, if it doesn't I will try to create an image of the tables.
I have to admit I'm failing to completely understand the model you wish to implement, but there is an interesting quote...
However I don't know to which
guestbook post the image is connected
(I do ofcourse know it the other way
around).
If you know an association one way, you should be able to use the associaton in both directions? I'm assuming you have a table that includes "post_id, image_id", or something?
It may be that the table is only indexed post_id first, in which case querying that table by image_id may be slow, but then you can just include a new index with image_id first?
If you can give examples of the table structure you have at present, and an example of the query you can't fullfil, we may be able to help you further.
Sounds like you want a foreign key constraint.
Update: Completely misunderstood the question, apparently.
There are two approaches here:
As it currently stands, there is nothing in the schema that would prohibit linking the same image from multiple resources. If that is desired, then a foreign key constraint and an index for the backreference is probably the best solution, although it will not scale well, and requires additional computation (because the rights on the image need to be the union of the rights of the refering resources).
The alternative is to create some kind of inheritance schema, where there is a table listing "resources" (that effectively just contains identifiers) that is referenced as a foreign key from the actual resource tables and the images table; the only constraint that cannot be expressed in plain SQL is that different resources may not share the same identifier.
Create two SELECT clauses, each having the correct joins to the correct tables, and then combine the output of the two SELECT clauses together using a UNION statement.
SELECT field1, field2
FROM table1
JOIN table2 on table1.PK = table2.FK
WHERE table1.selector = 1
UNION SELECT field1, field2
FROM table1
JOIN table3 on table1.PK = table3.FK
WHERE table1.selector = 2

MySQL - Coming up with a Unique Key for each record, not the primary Key

Ok this is a tricky one to explain.
I am creating an app that will have PAGES, currently I'm using PageID as the key to SEL the record.
The issue I'm having now is that I want users to be able to EDIT pages, but not lose the previous page (for history, recording keeping reasons, like a changelog or wiki page history).
This is making me think I need a new field in the PAGE table that acts as the pageID, but isn't the Primary Key that is auto-incremented every time a row is added.
Google Docs has a DOCID: /Doc?docid=0Af_mFtumB56WZGM4d3Y3d2JfMTNjcDlkemRjeg
That way I can have multiple records with the same Doc ID, and show a history change log based on the dataAdded field. And when a user wants to view that DOCID, I simply pull the most recent one.
Thoughts? I appreciate your smart thinking to point me in the right direction!
You're on the right track. What you need is a history or revision id, and a document id. The history id would be the primary key, but you would also have a key on the document id for query purposes.
With history tracking, you add a bit more complexity to your application. You have to be careful that the main view of the document is showing the current history revision (ie. largest history id for a given document id).
As well, if you are storing large documents, every edit is essentially going to add another copy of the document to your database, and the table will quickly grow very large. You might want to consider implementing some kind of "diff" storage, where you store only the changes to the document and not the full thing, or keeping history edits in a separate table for history-searching only.
UUID() creates a randomly generated 128bit number, like
'6ccd780c-baba-1026-9564-0040f4311e29'
This number will not be repeated in a few millions years.
//note most digits are based upon timestamp and machine information, so many of the digits will be similar upon repeated calls, but it will always be unique.
Keep an audit table with the history of the changes. This will allow you to go back if you need to roll back the changes or view change history for example.
You might model it like this:
An app has multiple pages, a page has multiple versions (each with some version info (e.g., date, edit count), and a foreign key to its page)
Viewing a page shows the most recent version
Saving an edit creates a new version
each document is really a revision:
doc - (doc_id)
revision - (rev_id, doc_id, version_num, name, description, content, author_id, active tinyint default 1)
then you can open any content with just the rev_id: /view?id=21981
select * from revision r, doc d where r.rev_id = ? and r.doc_id = d.doc_id
This sounds like a good job for two tables to me. You might have one page_header table and one page_content table. The header table would hold static info like title, categorization (whatever) and the content table would hold the actual editable content. Each time the user updates the page, insert a new page_content record versus updating an existing one. When you display the page just make sure you grab the latest page_content record. This is a simple way to keep a history and roll back if needed.
Good luck!