логин: 
Другие записи за это число:
2011/03/19_1 - Кстати про MySQL давно хотел спросить
<< предыдущая заметкаследующая заметка >>
19 марта 2011
таинственная хуйня MySQL

UPD: Вопрос решен, всем спасибо, последовал вашим советам:

Вытянул из структуры таблицы все поля:
preg_match_all("/\n\s*`([^`]+)`/si",$s,$m); $s='`'.implode('`,`',$m[1]).'`';

Получается типа такого: `Date`,`Header`,`Body`,`Access`,`DateUpdate`,`view_counter`,`num`,`DateDatetime`,`DateDate`,`opt`

И команду вставки оборудую именно этими подробностями:

msq("INSERT INTO `$table2` ($s) SELECT $s FROM `$table`");

БЫЛО:

Ситуация. Есть некая таблица. Создается такая же по структуре, чтобы скопировать. Полный код операции:

DROP TABLE IF EXISTS `ss1`;

CREATE TABLE IF NOT EXISTS `ss1` (
`Date` varchar(128) NOT NULL,
`Header` varchar(255) NOT NULL default '',
`Body` mediumtext NOT NULL COMMENT 'Текст заметки (до 16М)',
`Access` enum('all','podzamok','admin') NOT NULL,
`DateDatetime` int(11) NOT NULL default '0',
`DateDate` int(11) NOT NULL default '0',
`DateUpdate` int(10) unsigned NOT NULL default '0',
`num` int(10) unsigned NOT NULL auto_increment,
`view_counter` int(10) unsigned NOT NULL default '0',

`opt` text NOT NULL,
UNIQUE KEY `num` (`num`),
KEY `Date` (`Date`),
KEY `Access` (`Access`),
KEY `DateDatetime` (`DateDatetime`),
KEY `DateDate` (`DateDate`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COMMENT='Заметки блога' AUTO_INCREMENT=1 ;

INSERT INTO `ss1` SELECT * FROM `dnevnik_zapisi`;

Копирует примерно половину записей (140 из 212) и выдает ошибку:
#1062 — Duplicate entry '1281643201' for key 1

Теперь берем ту же команду, но строки, что я выделил зеленым, заменяем на ТОЧНО ТАКИЕ ЖЕ, ТОЛЬКО ПЕРЕЧИСЛЕННЫЕ В ДРУГОМ ПОРЯДКЕ:

`DateUpdate` int(10) unsigned NOT NULL default '0',
`view_counter` int(10) unsigned NOT NULL default '0',
`num` int(10) unsigned NOT NULL auto_increment,
`DateDatetime` int(11) NOT NULL default '0',
`DateDate` int(11) NOT NULL default '0',

Все прекрасно копирует.

Скажите, это вообще как понимать? Следует сюда добавить, что значение Duplicate entry '1281643201' в копируемой таблице встречается только в одной записи в поле `DateDatetime`.

Вопрос, почему у меня названы так переменные и зачем они мне вообще, не являются в данной ситуации важными для понимания, чем объясняется глюк MySQL.

У вас есть объяснение феномену?
Что, MySQL копирует таблицу командой «INSERT INTO xxx SELECT * FROM» как слепая лошадь — не глядя на имена полей, просто по порядку?

<< предыдущая заметка следующая заметка >>
пожаловаться на эту публикацию администрации портала
архив понравившихся мне ссылок
Оставить комментарий
Windows Safari Chrome
0
0
Sling (#824708)
Именно по порядку. Если сопоставлять имена полей, фигня какоая-то получится.
Что если совпадает только часть? Совпадающие один к одному вставлять, а остальные по порядку? А если совпадающих нету, то просто по порядку тогда. Слишком как-то бредово получается.

Как показала практика, вообще лучще все колонки в апдейтах/инсёртах перечислять поимённо. Это избавляет от многих проблем. Совсем недавно на своём проекта с этим сталкивался.
Linux Firefox
 Москва
0
0
И как мне записать это копирование одной командой, не вынимая базу к себе в скрипт PHP, чтобы засунуть обратно?
Windows Firefox
2
0
quantum (#644921)
insert into table2 (id, name)
SELECT id,name FROM table1
Windows Firefox
0
0
quantum (#644921)
>Что, MySQL копирует таблицу командой «INSERT INTO xxx SELECT * FROM» как слепая лошадь — не глядя на имена полей, просто по порядку?

Вобщем-то так и есть. И это делает нетолько mysql
Linux Firefox
 Москва
0
2
Еще японские атомщики, я понял ;)
Windows Firefox
1
1
quantum (#644921)
mysql не единственная субд. mssql и postgre точно такие же. И наверняка подавляющее большинство. Скорее всего это записано в стандарте sql.

А шутки про японских атомщиков у нас, на ДВ, менее смешные)
Nokia-E90 Safari
 Москва
2
0
Leonid Kaganov
Держись, Дальний восток! Советую обзавестись дозиметром. Я только что как раз читал новости Фукуямы-1, потом достал дозиметр и проверил фон. Его, понятное дело, быть в Москве не может, даже если вся Япония превратится в распадающийся уран, но по привычке иногда меряю. 17-18, как обычно.
Linux Opera
4
0
Все правильно делает mysql. Что просишь, то и делает. Говоря "SELECT *" ты говоришь: "мне все поля, в любом порядке, мне пофигу". А делая INSERT и не указывая списка полей, ты говоришь "ну вставь там как-нибудь".

Если не хочешь и дальше отстреливать себе ногу, забудь, что в SQL есть конструкции со звездочкой.
Linux Opera
0
0
В таблице все строки должны быть уникальны. Проще всего этого добиться добавив поле int(11) и сказав mysql, что это primary key. Оно само сообразит, что его надо увеличивать автоматически.

А тут я не вижу явно указанного primary key. Похоже mysql просто берет подходящее по его мнению поле и делает его первичным ключом. Уникальным, естественно. Меняешь порядок, выбор mysql насчет первичного ключа тоже меняется.
Windows Firefox
0
0
quantum (#644921)
Видимо, смотрели плохо

`num` int(10) unsigned NOT NULL auto_increment,
..
UNIQUE KEY `num` (`num`),

>Похоже mysql просто берет подходящее по его мнению поле и делает его первичным ключом. Уникальным, естественно.

mysql само ничего делать не будет
Windows Safari Chrome
1
0
(Пардон плиз, если этот коммент отправлен дважды, - не со зла!)
Одной командой можно и создать и заполнить новую таблицу:
CREATE TABLE IF NOT EXISTS `ss1` (
`Date` varchar(128) NOT NULL,
`Header` varchar(255) NOT NULL default '',
`Body` mediumtext NOT NULL COMMENT 'Текст заметки (до 16М)',
`Access` enum('all','podzamok','admin') NOT NULL,
`DateDatetime` int(11) NOT NULL default '0',
`DateDate` int(11) NOT NULL default '0',
`DateUpdate` int(10) unsigned NOT NULL default '0',
`num` int(10) unsigned NOT NULL auto_increment,
`view_counter` int(10) unsigned NOT NULL default '0',
`opt` text NOT NULL,
UNIQUE KEY `num` (`num`),
KEY `Date` (`Date`),
KEY `Access` (`Access`),
KEY `DateDatetime` (`DateDatetime`),
KEY `DateDate` (`DateDate`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COMMENT='Заметки блога' AUTO_INCREMENT=1
as
SELECT
`Date`,
`Header`,
`Body`,
`Access`,
`DateDatetime`,
`DateDate`,
`DateUpdate`,
`num`,
`view_counter`,
`opt`
FROM `dnevnik_zapisi`;

(можно добавить "where..." и заполнить выборочно, - т.е. пишите любой "select" какой вам надо..)

P.S.
Лошадь не слепая, у неё на глазах шоры не без резону.. лишнего увидит - чего-нибудь не так поймёт :)
P.P.S.
А вот ещё представьте себе что в каком-нибудь аппе закодирован "insert into t1 as select * from t2".. А потом где-то через год кто-то взял и добавил новую колонку к t1 (ну или к t2, какая разница?). Тогда этот апп сразу же превратиться в ту самую слепую лошадь. (вот вам пожалуйста обратная сторона удобства "звездючных" конструкций)..
Linux Firefox
 Москва
0
0
Ага, спасибо.
Пойду писать перечисление списка полей для универсального случая.

всего комментариев: 12

<< предыдущая заметка следующая заметка >>