creating a sorted list in database - mysql

So basically I have a table named contents where users can store their items. Normally here when a user add a new item, The item is added at the end of rows.
Something like:
|ID | Name | Item |
--------------------
|1 | Jack | pen |
|2 | Mark | apple |
|3 | albert| orange|
|4 | Jack | pencil|
But the problem with above is that it might take a lot of time when we have a lot of users and items like Jack's first item is at row ID 40 and item #2 is at 1000048 and so which might take a while to search for all the items that belongs to Jack So I was wondering how to sort them up by their Name so it could be something like:
|ID | Name | Item |
--------------------
|1 | Jack | pen |
|2 | Jack | pencil|
|3 | Mark | apple |
|4 | albert| orange|
And if the user added a new item it should be added to the end of his rows list.
All replies are much appreciated, Thank:)

Add index(es) for any column (or combination of columns) you want to search for and/or want to order by.
Do not reorder the table, nor re-number the ids.
If you are talking about 1000 rows, you are unlikely to notice any performance problems even if you don't do proper indexing or normalization. With a million rows, you will notice.

Related

MySQL: How can I obtain a distinct list of words from a string column using a stored procedure

I've been agonising over this for the past day and a half, and while I've attempted to write my own function using examples that people gave, it's been incredibly difficult to do seeing as the strings I'm obtaining might be anything from 30 words to 1000 words long
I've a database that looks something like this
|NewsItemID|NewsItemString |
============================================
| 1 | This is the first news item |
| 2 | This is the second news item |
| 3 | This is the third news article |
============================================
How can I use a stored procedure to end up with a list like this:
|Word |
==========
|This |
|is |
|the |
|first |
|news |
|item |
|second |
|third |
|article |

Build complex result table with dynamic columns

I have a question - trying to find a solution here, but that what I see is not as my situation. So:
In TABLE1 we have some article descriptions
ID | Name
1 | Doors
2 | Chairs
In TABLE2 we have a article properties
ID |ID_article | Descr
1 |1 | Type
2 |1 | Material
3 |2 | Height
4 |2 | Width
5 |2 | Toll
In TABLE3 we have a article list with properties values like
Article | ID_art_descr | ID_art_prop | Value
Model1 | 1 | 1 | Solid
Model1 | 1 | 2 | Wood
Model2 | 1 | 1 | Solid
Model2 | 1 | 2 | Steel
The goal is to build a table, which list article from given group with properties for that group. for example, for doors, the table must have columns:
Article | Type | Material
Model1 | Solid | Wood
Model2 | Solid | Steel
For Chairs, the table must have other columns:
Article | Height | Width | Toll
........
So for every article group, the columns count and lables will be different. I was write script on aspx and php which do this, but that method have difficults with sorting or filtering the result table (in some case, we have more than 10k ot rows). So I wonder is there a way to generate a result table on MySQL?
And here is the sqlfiddle description for Table1, Table2 and Table3:
http://sqlfiddle.com/#!2/53e32/1
Thank you strawberry

MySQL how to rank objects by similarity of multiple property rows

Hello all and a Happy New Year
SITUATION:
I have some tables in MySQL db:
Scores:
(Unique ID, unique (objectID, metricID))
| ID | ObjectID | MetricID | Score |
|--------+----------+----------+----------|
|0 | 1 | 7 | 0 |
|1 | 5 | 3 | 13 |
|2 | 7 | 2 | 78 |
|3 | 7 | 3 | 22 |
|.....
|--------+----------+----------+----------|
Objects:
(unique ID, unique ObjectName)
| ID | ObjectName |
|--------+------------|
|0 | Ook |
|1 | Oop |
|2 | Oww |
|3 | Oat |
|.....
|--------+------------|
Metrics:
(unique ID, unique MetricName)
| ID | MetricName |
|--------+------------|
|0 | Moo |
|1 | Mar |
|2 | Mee |
|3 | Meep |
|.....
|--------+------------|
For a given object ID:
There will be a number of scores between '0' and 'one per metric'
REQUIREMENT:
For a given ObjectID, I want to return a sorted list based on the following criteria:
Returned rows ranked in order of similarity to the provided object
Returned rows not to include provided object
(this is the hard bit I think) Order of similarity is determined by an object's "score distance" from the provided object based on the numeric offset/difference of its score from the provided object's score for any metric for which there is an entry for both the provided and the currently-examined objects
Contains objectID, Object name, score difference (or something similar)
PROBLEM STATEMENT:
I don't know the correct SQL syntax to use for this, and my experiments so far have failed. I would like to do as much of this work in the DB as possible and have little or none of this work done in nasty for-loops in the code or similar.
ADDITIONAL NON-FUNCTIONALS
At present there are only 200 rows in the Scores table. My calculations show that ultimately there may be up to around 2,000,000 rows, but probably no more.
The Objects table will only ever have up to around 5000 rows
The Metrics table will only ever have up to around 400 rows
Here's an approach to order objects based on their similarity to object 1:
select other.ObjectID
, avg(abs(target.Score - other.Score)) as Delta
from Scores target
join Scores other
on other.MetricID = target.MetricID
and other.ObjectID <> target.ObjectID
where target.ObjectID = 1
group by
other.ObjectID
order by
Delta
Similarity is defined as the average difference in common metrics. Objects that do not share at least one metric with object 1 are not listed. If this answer makes wrong assumptions, feel free to clarify your question :)
Live example at SQL Fiddle.

SQL: Compare if column values in two tables are equal

I'm working on mysql and have two tables with the same schema:
preTrial
|id|accusedId|articleid|
------------------------
|1 | 1 | 1 |
|2 | 1 | 2 |
|3 | 1 | 3 |
|4 | 2 | 1 |
|5 | 2 | 2 |
trial
|id|accusedId|articleid|
------------------------
|1 | 1 | 1 |
|2 | 1 | 2 |
|3 | 2 | 1 |
|4 | 2 | 2 |
I want to get those accusedIds where all the articleIds of the first and the second tables are equal.
The above example should only return the accusedId 2, cause for accusedId 1 there is no articleId 3 in the second table.
I hope you understand what i mean. I'm currently writing my thesis in law, and the the time i was into sql is long gone by. Of course i already did some research, and tried several joins, but i was not able to find a solution. Hopefully you can help me.
Try something like this:
select a.accusedId , sum(a.accusedid) as cnt_a, sum(coalesce(b.accusedId, 0)) as cnt_b
from a left join b on a.accusedId = b.accusedId and a.articleId = b.articleId
group by accusedId
having cnt_a = cnt_b
I haven't even run that, so it might be a little off, but give it a lash. What it's doing is returning zeroes for a row in a not matched by b, so the HAVING clause will filter your grouped results to those where the article counts are equal.

Database structure for a classifieds website

I am developing a classifieds website similar to Quickr.com.
The main problem is that each category requires a different set of properties. For example, for a mobile phone the attributes might be Manufacturer, Operating System, Is Touch Screen, Is 3G enabled etc... Whereas for an apartment the attributes are Number of bedrooms, Is furnished, Which floor, total area etc. Since the attributes and the number of attributes varies for each category, I am keeping the attributes and their values in separate tables.
My current database structure is
Table classifieds_ads
This table stores all the ads. One record per ad.
ad_id
ad_title
ad_desc
ad_created_on
cat_id
Sample data
-----------------------------------------------------------------------------------------------
|ad_id | ad_title | ad_desc | ad_created_on | cat_id |
-----------------------------------------------------------------------------------------------
|1 | Nokia Phone | Nokia n97 phone for sale. Excellent condition | <timestamp> | 2 |
-----------------------------------------------------------------------------------------------
Table classifieds_cat
This table stores all the available category. cat_id in classifieds_ads table relates to cat_id in this table.
cat_id
category
parent_cid
Sample data
-------------------------------------------
|cat_id| category | parent_cid |
-------------------------------------------
|1 | Electronics | NULL |
|2 | Mobile Phone | 1 |
|3 | Apartments | NULL |
|4 | Apartments - Sale | 3 |
-------------------------------------------
Table classifieds_attribute
This table contains all the available attributes for a particular category. Relates to classifieds_cat table.
attr_id
cat_id
input_type
attr_label
attr_name
Sample data
-----------------------------------------------------------
|attr_id | cat_id | attr_label | attr_name |
-----------------------------------------------------------
|1 | 2 | Operating System | Operating_System |
|2 | 2 | Is Touch Screen | Touch_Screen |
|3 | 2 | Manufacturer | Manufacturer |
|4 | 3 | Bedrooms | Bedrooms |
|5 | 3 | Total Area | Area |
|6 | 3 | Posted By | Posted_By |
-----------------------------------------------------------
Table classifieds_attr_value
This table stores the attribute value for each ad in classifieds_ads table.
attr_val_id
attr_id
ad_id
attr_val
Sample data
---------------------------------------------
|attr_val_id | attr_id | ad_id | attr_val |
---------------------------------------------
|1 | 1 | 1 | Symbian OS |
|2 | 2 | 1 | 1 |
|3 | 3 | 1 | Nokia |
---------------------------------------------
========
Is this design okay?
Is it possible to index this data with solr?
How can I perform a faceted search on this data?
Does MySQL support field collapsing like solr?
My suggestion is to remove cat_id from the classifieds_attribute table, then create a new table.
The new table would look like:
cat_attr | id | cat_id | attr_id
This should help you decrease redundancy.
Your design is fine, although I question why you are using hierarchical categories. I understand that you want to organize categories from an end-user standpoint. The hierarchy helps them drill down to the category that they are looking for. However, your schema allows for attribute values at every level. I would suggest that you only need (or possibly want) attributes at the leaf level.
It is certainly possible that you could come up with attributes that would be applicable at higher levels, but this would drastically complicate your management of the data since you'd have to spend a lot of time thinking about exactly how high up the chain a certain attribute belongs and whether or not there is some reason why a lower level might be an exception to the parent rule and so forth.
It also certainly over complicates your retrieveal as well - which is part of the reason for your question, I think.
I would suggest creating an additional table that will be used to manage the hierarchy of categories above the leaf level. It would look exactly like your classifieds_cat table except the involuted relationship will obviously be to the new table. Then classifieds_cat.parent_cid becomes an FK to the new table rather than an involuted FK to classifieds_cat.
I think this schema change will reduce your application and data management complexity.