2010-12-28 8 views
0

Ich baue eine Datenbank, es erfordert jede Zeile über 60.000 Bytes (sehr nah an MySQL maximale Zeilengröße, im Grunde viele varchar (500) Anweisungen [notwendig]). Nun, soweit ich weiß, ist das im Myismus in Ordnung.MYSQL innodb mit fast Max Anzahl von Varchar-Spalten (60K)

Allerdings denke ich Innodb aufgrund seiner Zeilensperre Verhalten (ich bekomme viele Updates zu meiner Tabelle). Ich habe gerade einige beunruhigende Informationen bezüglich innodb gefunden, das nicht große Reihen mag (etwas ungefähr 8000 Bytes maximal oder etwas).

Also, da meine Tabelle Reihen von jeweils ca. 60.000 (!) Bytes haben wird, ist das ein Problem für innodb? Ist das ein großes Problem? Deal Breaker? Was würdest du vorschlagen?

Tabelle: ID (int, AutoInc, Primärschlüssel), varchar (500), varchar (500) ... wiederholen ... varchar (500) bis zum Ende der Tabelle

erreicht
+0

Bitte erläutern Sie die Zusammensetzung Ihrer Zeilen. Blob- und Textspalten zum Beispiel haben leicht unterschiedliche Regeln für die Beurteilung der Größe. –

+0

Ich habe eine Erklärung meiner Zeilen hinzugefügt. insgesamt sind etwa 7 Millionen Zeilen. – David19801

+0

Ich würde vorschlagen, MySQL nicht zu verwenden. Gibt es einen Grund, warum Sie MySQL anstelle einer NoSQL-Lösung verwenden möchten? – Wolph

Antwort

0

nicht sicher, warum Sie ‚gewählt habe 120 varchar (500) Spalten zu verwenden, aber ich denke, Sie besser dran Zeilen einfügen würde - etwa so:

drop table if exists users; 
create table users 
(
user_id int unsigned not null auto_increment primary key, 
username varbinary(32) unique not null, 
next_note_id smallint unsigned not null default 0 
) 
engine=innodb; 

drop table if exists user_notes; 
create table user_notes 
(
user_id int unsigned not null, 
note_id smallint unsigned not null, 
note varchar(512) not null, 
primary key (user_id, note_id) -- clustered composite PK 
) 
engine=innodb; 

delimiter # 

create trigger user_notes_before_ins_trig before insert on user_notes 
for each row 
begin 
declare v_id int unsigned default 0; 

    select next_note_id + 1 into v_id from users where user_id = new.user_id; 
    set new.note_id = v_id; 
    update users set next_note_id = v_id where user_id = new.user_id; 
end# 

delimiter ; 

insert into users (username) values ('f00'),('bar'); 

insert into user_notes (user_id, note) values 
(1,'user 1 note 1'), (1,'user 1 note 2'), (1,'user 1 note 3'), 
(2,'user 2 note 1'); 

select * from users; 
user_id username next_note_id 
======= ======== ============ 
1   f00  3 
2   bar  1 

select * from user_notes; 
user_id note_id note 
======= ======= ==== 
1   1  user 1 note 1 
1   2  user 1 note 2 
1   3  user 1 note 3 
2   1  user 2 note 1 

hoffe, es hilft :)

+0

Interessant, aber mit 7 Millionen Zeilen, würde dies 700 Millionen bedeuten, wenn 100 Varchare jeweils?> – David19801

+0

In meinem Beispiel, wenn jeder Benutzer 100 Notizen hat und es 7 Millionen Benutzer gibt, dann hätten Sie (7 Millionen Benutzer * 100 Notizen) = 700 Millionen Datenzeilen. Wenn Sie sich darüber Sorgen machen, können Sie meine Antwort hier überprüfen http://stackoverflow.com/questions/4419499/mysql-nosql-help-me-to-choose-the-right-one-on-a-/ 4421601 # 4421601 (man denke nur an ein Forum als Benutzer und einen Thread als Notiz - 500 Millionen Zeilen mit einer Abfrage-Laufzeit von 0,02 Sekunden unter Last) –

0

InnoDB hat die gleiche Grenze von 64 KB für Zeilengröße. Außerdem werden die Zeilengrößen auf die halbe Seitengröße beschränkt, aber die Spalten varbinary, varchar, blob oder text sind darin nicht enthalten. Standardmäßig ist die Seitengröße von InnoDB 16K, daher haben Sie am Ende das 8K-Limit. Aber Sie sollten für die Konvertierung in Ordnung sein, da Ihre Spalten Varchar sind. Wenn Sie das InnoDB-Plugin nicht verwenden, ist das verwendete Zeilenspeicherformat ("compact") möglicherweise ineffizient, da der varchar-Inhalt jenseits von 768 Bytes in zusätzlichen 16.000 Seiten und in diesen 4 zusätzlichen Seiten gespeichert wird case (ceil (60/16)) kann irgendwo im InnoDB-Pool gespeichert werden (kein Problem, wenn Ihr Dataset in den InnoDB-Pufferpool passt). Ich würde das InnoDB-Plugin Dynamic row Format verwenden.

Beachten Sie, dass die Konvertierung großer Tabellen sehr lange dauert. Versuchen Sie zuerst, eine Sicherung auf Ihrem Entwicklungscomputer zu konvertieren.

+0

"Der Varchar-Inhalt über 768 Bytes hinaus ist in zusätzlichen 16K-Seiten gespeichert" Das ist sehr interessant. Jedes varchar wird latin1 sein, was ich als 1byte pro Buchstabe ansehe. Wäre also ein varchar (500) in Ordnung? Ist die 768 Grenze pro Varchar oder für alle Varchare in der Zeile addiert? Prost – David19801

+0

Das 768 Byte In-Zeile-Speicherlimit ist für alle V/V/B/T-Spalten zusammen.Wenn Sie also insgesamt mehr als 768 Byte haben, werden zusätzliche Seiten von InnoDB verwendet, um den Inhalt über 768 Byte hinaus zu speichern (im alten "kompakten" Format). Wenn Sie das neue dynamische Zeilenformat verwenden, werden alle v/v/b/t-Spalten in zusätzlichen Seiten gespeichert, da dadurch die b-tree-Indizes kleiner werden, was die Indexoperationen beschleunigt (weniger Speicherauslagerung durch die CPU). Seit MySQL 5.0.3 beträgt die maximale Länge eines einzelnen varchar 65.535 Bytes. http://dev.mysql.com/doc/refman/5.0/en/char.html –

+0

Wie sicher bist du, dass es für alle c/b/t Spalten ** ZUSAMMEN **? Ich hätte gedacht, dass das für jeden ist, wobei 8000 das absolute Maximum von allem ist. 768 scheint einfach viel zu niedrig ... – David19801