SQL sentence only takes id's of less than 6 digits MYSQL - mysql

I'm trying to understand why this is happening but I couldn't find anything in the internet.
I have a table of meds(called Medicamento) which has 23600 elements in it.
When I try to take an element using the IdMed column it only takes the values with less than 6 digits. Example 1:
SELECT * FROM `Medicamento` WHERE IdMed=100
Example 2:
SELECT * FROM `Medicamento` WHERE IdMed=200703
At this point I thought that the med with that Id was not created so I did this last query which made me not knowing where the mistake is:
SELECT * FROM `Medicamento` WHERE IdMed>200702
Result:
As you can see the first element is the one with the 200703 Id. What I cannot understand is why it takes elemnts with Id's such as 12700 or 100 but it doesn't take elements with Id's of 6 numbers. I thought it could be a matter of formats but I didn't find anything helpful.
Data of the table was taken from 2 different .xlsx files, that's why I thought about formats.
PD: Sorry for my bad English. I hope the problem is understood.
EDIT:
Table data types

In a nutshell, what's happening is your value is losing precision because you're using an inaccurate data type. float is for floating point numbers, and ideally shouldn't normally be used as a primary key. your best bet is to change this to an integer data type instead. By the looks of the comments, this may not be viable, you're probably best off to create another column and use THAT as the primary key instead. What's likely happening is for example with 200703, it's potentially being stored in the database as 200703.000001 or 2007002.99999 and you're searching for a value that's not an exact match to how the database is storing it.
As a suggestion, you may want to change your current float column to a double column instead to retain a little more precision beyond the decimal point.

Related

Efficiency of tables that have a mapping to another table where their real value is held in MySQL

I am developing a small survey system that consists on inserting all the form data at once (around 90 questions will be answered). Also, you can consult the data later . Having this in mind, I wanted to ask what were the advantages of using a schema like such:
I have several questions in the survey that will have multiple checkboxes (some have 15+), and people will be able to select MULTIPLE of those checkboxes as their answer, and I will store all their selected options in the DB. I am achieving this by using the same name attribute in all those checkbox inputs (belonging to a question) as such: name="q_01[]". The "problem" here (not really a problem, more like a performance/storage optimization enhancing) is that I don't want to store the same values over and over. Say, if I had 20 checkboxes, and their values (attribute in HTML value="Real Value") were something long like Strawberry, Something, etc.. etc.., I would be duplicating the same value over and over, leading to space being wasted.
Instead, I want to store an integer, that will map to a table that holds the real value. That way, I would only store 4 bytes, instead of (UP TO) 255 chars as VARCHAR.
I have heard of such systems, but I have not done it myself, and I don't know any namings or conventions. Could you guys point me in the right direction (by posting an example/youtube vid or a page where there is one)? How are these tables called? I know the basics of foreign keys, and relational tables, so I know the answer lays somewhere in there.
Also, if you could include or give me a hint of how I could query such tables, that would be awesome!
Thank you for your help in advance!
Cheers!
If a question has 15 possible answers which can be chosen independently of each other, then each possible answer will become one table column of your answer table, having column names like strawberry, raspberry, etc. The name of the column doesn't have to be represented in the database itself (although it will be present in the information schema columns table https://dev.mysql.com/doc/refman/5.0/en/columns-table.html belonging to MySQL that, if for advance use cases, you can read from your software). Your columns for taking the checkbox values will all be boolean or tinyint(1); these values should neither contain the string strawberry nor some foreign key to a record containing strawberry.
See the SET datatype.
See SMALLINT UNSIGNED, it has 16 bits, each of which could indicate one answer.
More on the latter case: Best datatype to store a long number made of 0 and 1

Field with numbers and letters

I have a table in which i have a field that requires 3 letters and 3 numbers (that have to between the values 2000 & 7000).
I've been reading around, and i'm still not sure which is the better way to handle this issue, whether it can be with a simple datatype, say for instance char(6), or if there has to be a field that contains only the 3 letters, and another field that contains the 3 numbers with a check restriction to ensure that the values of that field are between 2000 & 7000.
Any help that you can offer me, i would be glad. Thanks in advance
You may have to give more specificity about the requirements, but it sounds to me like a single column is the best option -- especially if order matters. If the letters and numbers have meanings separately, then they should be in two columns. Otherwise, you'll just end up having to concatenate them together.
char(6) is fine as long as you know it will always be 6 characters exactly. You can't enforce such a specific limit as 2000 to 7000 at column level anyway (which is 4 numbers, isn't it?)
Every field should represent an attribute of the entities the table holds. In other words, if these three letters and three numbers represents different attributes, they should be in separate fields, otherwise (e.g. they are to represent a serial number) you can have them in one field.
Another approach is to think of a possible use case, like: Am I going to perform a query based on the second number? If your answer is yes, then they should be in separate fields, otherwise they represent one attribute and they should be in one field.
Hope it helps.
If the value is "one" value, use one column, say char(6), but...
Here's a surprising fact: mysql doesn't support CHECK constraints!
Mysql allows CHECK constraints to defined, however they are completely ignored and allowed only for comparability with SQL from other databases.
If you want to enforce a format, you'll need to use a trigger, but mysql doesn't support raising exceptions, so you'll have to use a work-around.
The best option is probably to use app code for validation.

mysql table design, large column size vs large number of rows

Please help me understand which of the following is better for scaling and performance.
Table: test
columns: id <int, primary key>, doc <int>, keyword <string>
The data i want to store is a pointer to the documents containing a particular keyword
Design 1:
have unique constraint on the keyword column and store the list of documents as an array
e.g id: 1, doc: [4,5,6], keyword: google
Design 2:
insert a row for each document
1 4 google
2 5 google
3 6 google
Lets the say the average number of documents a particular keyword would be found in is close to 100000. there may not be a max number of documents the keyword appears in.
You can forget about option 1 because there's no array data type in mysql.
To be honest if you want a scallable solution for this type of data I think you should look into a different type of database. Research more on NoSQL and 'key-value pair store database'.
With mysql, the best I can think of is your 2nd option, with the exception that you should create another table with a numeric ID and a list of unique keywords. That way, when you do your search you'll first look up the ID, then filter the big table by the ID instead of string. Numeric comparison is faster than string comparison.
A lot of factors come into scaling and performance so it's not usually a good idea to try to optimise unknowns early in development.
For database design I find it's usually best to go with the more correct normalised approach (your design 2) and then worry about the scaling and performance if it becomes an issue. You can then de-normalise certain areas or take other approaches depending on what issues you face.
Your design option 1 is likely to hit other issues more immediately with the inability to join the doc column with another table, as well as complexities updating and searching it as well.
Design 1 is potentially limited by MySQL's row size limit.
Design 2 makes the most sense to me. What if you need to remove one of those values? You just delete a row rather than having to search through and update an array. It's also nice because it allows you to limit the size of your results if necessary (e.g., for pagination).
You might also consider creating a many-to-many relationship between this table and a keywords table instead of storing keywords as a field here.

how to create a look up table

I have a spreadsheet that I have imported into MySQL.It has many rows of entries, including gambling odds i.e 2/1, or 7/2. Unfortunately the gambling odds are read as varchar by MySQL which makes it impossible to do calculations on them. It was suggested that I create a look-up table, where the gambling odds can be converted to there decimal values. This makes sense. OK so the big question is how do I go about this? Should I create a separate table that lists gambling odds and equates these to their decimal equivalents, if so, how would I make queries such as, find all the rows that have odds at 2/1 from table 1, and multiply this by £1. Any suggestions please?
I think a lookup table is too hard to maintain, since there are an infinite number of possible odds combinations.
Instead, I would strongly suggest that you create a view over your base table, that has the various fields that contain the odds:
create view v_table as
select t.*,
OddsTop*1.0/OddsBottom as OddsNumeric,
OddsBottom*1.0/(OddsTop + OddsBottom) as OddsPvalue
from (select t.*,
cast(left(t.odds, locate('/', t.odds, '/')-1) as int) as OddsTop,
cast(substring(t.odds, locate('/', t.odds)+1, 100) as int) as OddsBottom,
from t
) t
You can easily calculate various types of information related to the odds. Here, I've shown how to get the top number, bottom number, odds as a floating point number, and the p-value equivalent.
As far as I know there is no datatype for it in MySQL. I would suggest not to create separate table as you suggest. If precision is not of utmost importance you can just store them as a decimal with a specific width and query with the decimal value. You can always convert it back to its fractional representation in the application layer. If simplicity matters you can store them as varchar. See here for a related question.
This is actually quite an interesting question. My two-bits suggests that "7/2" isn't actually being used as a number, so could be interpreted as being a "code", in the same way that country codes are used instead of the whole country name. I might be inclined to go with the lookup table, using the Odds as the key, and the multiplication factors as columns in each row for use in math. You could also control how much precision you'd like to use, as well as have queries for high-odds and low-odds very easily.
Not necessarily saying I'm right here, just find this an interesting one.

MySQL: optimal column type for searching

I've been inserting some numbers as INT UNSIGNED in MySQL database. I perform search on this column using "SELECT. tablename WHERE A LIKE 'B'. I'm coming across some number formats that are either too long for unsigned integer or have dashes in them like 123-456-789.
What are some good options for modifying the table here? I see two options (are there others?):
Make another column (VARCHAR(50)) to store numbers with dashes. When a search query detects numbers with dashes, look in this new column.
Recreate the table using a VARCHAR(50) instead of unsigned integer for this column in question.
I'm not sure which way is the better in terms of (a) database structure and (b) search speed. I'd love some inputs on this. Thank you.
Update: I guess I should have included more info.
These are order numbers. The numbers without dashes are for one store (A), and the one with dashes are for Amazon (B; 13 or 14 digits I think with two dashes). A's order numbers should be sortable. I'm not sure if B has to be since the numbers don't mean anything to me really (just a unique number).
If I remove the dashes and put them all together as big int, will there be any decrease in performance in the search queries?
the most important question is how you would like to use the data. What do you need? If you make a varchar, and then you would like to sort it as a number, you will not be able to, since it will be treating it as string..
you can always consider big int, however the question is: do you need dashes? or can you just ignore them on application level? if you need them, it means you need varchar. in that case it might make sense to have two columns if you want to be able to for example sort them as numbers, or perform any calculations. otherwise probably one makes more sense.
you should really provide more context about the problem
Mysql has the PROCEDURE ANALYSE , which helps you to identify with your existing data sets. here's some example.
Given you are running query WHERE A LIKE 'B' mainly. You can also try full text search if "A" varies a lot.
I think option 2 makes the most sense. Just add a new column as varchar(50), put everything in the int column into that varchar, and drop the int. Having 2 separate columns to maintain just isn't a good idea.