2 место Заготовка для работы с БД MySQL в кубике C#

  • Автор темы Автор темы WebBot
  • Дата начала Дата начала
  • Теги Теги
    mysql
Нет случайно ни у кого примера как можно профиль сохранить в blob целиком?
Пробовал через LOAD_FILE сделать, но видимо я не до конца что то понимаю, отрабатывает корректно, но ячейка остается пустой.
 
@WebBot Привет!

1) Спасибо огромнейшее за тему - прям очень помогла. Уже на старте получилось отказаться от таблиц\списков и сразу сделать все на мускуле!!

2) Один вопрос есть:

- может подскажете (или кто-нить еще знает) как в кубике зенки (свой код) мускульный запрос на несколько этажей разбить?
Например:

SELECT * FROM table1, table2, table3
WHERE table.example_id = 1
AND table.author_id = 2
AND table2.phone_id = table3.phone_id;

Так сильно удобней, чем одна строка на 10 горизонтальных скроллов :) Пробовал просто строку переносить - не работает :) ломается запрос

есть такая возможность?
 
По идее для этого надо перенос строк включить.
Скриншот 24-11-2019 190532.jpg
 
  • Спасибо
Реакции: lockerr
@oOmp - включил, не помогло

@WebBot - все сработало! спасибо!
 
Ответ на еще на один вопрос напишу тут, возможно для новичков он так же будет полезен.

Вопрос:
"Вот ты пишешь что если в шаблоне например будет 10 обычных кубиков для работы с базой, то каждый из них создаст новое подключение к mysql. Но ведь и при использовании твоего кода будет то же самое если шаблон будет состоять из множества отдельных кубиков, в каждом из которых нужно будет обращаться к базе."

Ответ:
Что бы такого не происходило, необходимо в самом первом кубике шаблона создать подключение/сессию и поместить объект db в так называемый context, с помощью которого этот объект можно получить в любом другом кубике C#.

То есть первый кубик шаблона может иметь примерно такой вид:

C#:
Развернуть Свернуть Копировать
string db_host = "localhost";     // хост
string db_user = "root";          // username для подключения к MySQL
string db_pswd = "";              // пароль для подключения к MySQL
string db_database = "mydb";      // название БД с которой будет работа
string db_charset = "utf8";       // кодировка данных в таблицах

DB db = new DB(db_host, db_user, db_pswd, db_database, db_charset);

// сохраняем объект в контексте что бы использовать его в других кубиках
project.Context["db"] = db;

А дальше в любом другом/последующем кубике C# мы можем получить этот объект из контекста и выполнять наши запросы в рамках того же самого подключения/сессии что и была создана первм кубиком.

Пример кубика где мы получаем наш объект из контекста и используем его:

C#:
Развернуть Свернуть Копировать
var db = project.Context["db"]; // получаем объект из контекста

db.query("LOCK TABLES accounts WRITE");

// берем 1 аккаунт имеющий статус = 0 (свободен) и при этом дольше всего не использовался ( OREDER BY use_time )

List<string> row = db.getRow("SELECT id, login, pswd FROM accounts WHERE status=0 ORDER BY use_time LIMIT 1");

if ( row.Count > 0 ){

    project.SendInfoToLog("Взяли аккаунт с логином "+row[1]+" в работу",true);

    // сохраняем id, логин и пароль в обычные переменные ZP для использования в других кубиках
    project.Variables["acc_id"].Value = row[0];
    project.Variables["acc_login"].Value = row[1];
    project.Variables["acc_pswd"].Value = row[2];

    // меняем статус у взятого аккаунта на 1 (это будет означать что он в работе и брать его нельзя)

    db.query("UPDATE accounts SET status=1 WHERE id="+row[0]);
}
else {
    project.SendInfoToLog("Не удалось взять аккаунт",true);
    db.query("UNLOCK TABLES");
    throw new Exception();
}

db.query("UNLOCK TABLES");

И если уж мы используем созданный в первом кубике объект в различных других кубиках (тем самым выполняя все запросы в рамках одной сессии), то в Bad End и Good End нам необходимо не забыть закрыть сессию.

Это может выглядеть так - Good End и Bad End ведут к кубику содержащему примерно такой код:
C#:
Развернуть Свернуть Копировать
var db = project.Context["db"];  // получаем объект из контекста

string acc_id = project.Variables["acc_id"].Value;

if ( acc_id != "" ){

    // получаем текущее юникс-время
    int unixtime = (int)(DateTime.UtcNow - new DateTime(1970,1,1)).TotalSeconds;

    // обратно устанавливаем статус=0 (свободен) и время последнего использования устанавливаем на текущее
    db.query("UPDATE accounts SET status=0, use_time="+unixtime.ToString()+" WHERE id="+acc_id);
}

// завершаем работу с БД
db.close();


На самом деле я сейчас здесь подчистую скопировал код из приложенного шаблона primer1.xmlz , который как раз и разбит на несколько кубиков - в первом подключение к бд и открытие сессии, в другом получение аккаунта, далее произвольные кубики (работа с взятым аккаунтом), а в Bad End и Good End освобождение аккаунта и завершение сессии mysql.

Посмотреть вложение 41748

В общем можете сами скачать primer1.xmlz и более детально изучить.
на версии 5,38,0 через project.Context уже не передает -
var db = project.Context["db"];
возвращает null )
даже через метод project.Context.Add
 
на версии 5,38,0 через project.Context уже не передает -
var db = project.Context["db"];
возвращает null )
даже через метод project.Context.Add
Проверить не могу, у меня 5.33
Но мои шаблоны где используется БД юзают разные люди и пока никто не сообщал что что-то перестало работать. Контекст используется везде в моих шаблонах.
 
Как поправить ошибку подскажите плиз: "CSharp OwnCode: db connect. Authentication method 'caching_sha2_password' not supported by any of the available plugins."
Скопировал MySql.Data.dll в папку ExternalAssemblies
 
Как поправить ошибку подскажите плиз: "CSharp OwnCode: db connect. Authentication method 'caching_sha2_password' not supported by any of the available plugins."
Скопировал MySql.Data.dll в папку ExternalAssemblies
Mysql 8 кажется используете?
Попробуйте версию по старее использовать.
можно в ПС поискать ;-)
 
  • Спасибо
Реакции: Shining
Подскажите в Версии 5.42 эту проблему так и не пофиксили?
Я сейчас хочу приступить к реализации работы многопотока с БД.
Имеет смысл проделать все выше указаное ?
 
Какую именно проблему?
У меня в шаблоне несколько кубиков подключения, и работы и БД, т.е. при много потоке, я сталнусь с проблемой, что несколько потоком могут брать одну и туже строку из таблицы ?
 
У меня в шаблоне несколько кубиков подключения, и работы и БД, т.е. при много потоке, я сталнусь с проблемой, что несколько потоком могут брать одну и туже строку из таблицы ?
Да будет такое, если не помечать строку что она в работе.
Я вышеприведенным кодом пользуюсь, все работает.
 
  • Спасибо
Реакции: Kostass
Подскажите а зачем нам кодом локать таблицу, разве оно само там не локается на стороне БД?

Такая проблема
NGFXCqd.png


Что делать? До этого стандартным кубиком работал, запускал в 50-100 потоков, было норм, но только при 100 потока в админку не логинило писало много соединений
А сейчас запустил 50 потоков и вообще намертво лег пхпмайадмин, пишет 500 ошибку. В чем дело? Почему стало хуже? Стоит ли добавлять max_user_connections?

Плюс ко всему я смотрю в трассировке, половина шабов повисла на кубике как раз с мускулем. А зачем на нем виснуть???
 
Последнее редактирование:
Что не так делаю подскажите плизз:
C#:
Развернуть Свернуть Копировать
string db_host = project.Variables["server"].Value;      // хост
string db_user = project.Variables["db_login"].Value;    // username для подключения к MySQL
string db_pswd = project.Variables["db_pass"].Value;     // пароль для подключения к MySQL
string db_database = project.Variables["db_name"].Value; // название БД с которой будет работа
string db_charset = "utf8";       // кодировка данных в таблицах


// сохраняем объект в контексте что бы использовать его в других кубиках
project.Context["db"] = db;
 
Что не так делаю подскажите плизз:
C#:
Развернуть Свернуть Копировать
string db_host = project.Variables["server"].Value;      // хост
string db_user = project.Variables["db_login"].Value;    // username для подключения к MySQL
string db_pswd = project.Variables["db_pass"].Value;     // пароль для подключения к MySQL
string db_database = project.Variables["db_name"].Value; // название БД с которой будет работа
string db_charset = "utf8";       // кодировка данных в таблицах


// сохраняем объект в контексте что бы использовать его в других кубиках
project.Context["db"] = db;
А без подстановки переменных работает?
 
четко доступно с примерами... спасибо .. но прежде чем начать пробывать хотелось бы уточнить:
ориентировочная структура базы простая 3-4 таблицы не больше 5 лямов записей примерно и выполняя парсинг добавлять туда записи с проверкой на дубли или может для таких объемов нету вообще смысла вникать в мускл ? - щас переделал веб парсинг на пост/гет запросы скорость утсраивает/ресурсы освободил ... но вот размер списка спаршенных данных который растет с каждым днем ... незнаю даже.. может ктото поделится опытом сколько список ЗП тянет чтобы не тормозило.. речь не только о записи данных а проверка на наличие уже в списке

система вин2012 какую бд ставить? mysql 8 ? но есть web-community и просто community... а потом создавать базу через командндую строку или phpmyadmin както ставить ?
в общем подскажите как проще всего что и как поставить. спасибо
 
четко доступно с примерами... спасибо .. но прежде чем начать пробывать хотелось бы уточнить:
ориентировочная структура базы простая 3-4 таблицы не больше 5 лямов записей примерно и выполняя парсинг добавлять туда записи с проверкой на дубли или может для таких объемов нету вообще смысла вникать в мускл ? - щас переделал веб парсинг на пост/гет запросы скорость утсраивает/ресурсы освободил ... но вот размер списка спаршенных данных который растет с каждым днем ... незнаю даже.. может ктото поделится опытом сколько список ЗП тянет чтобы не тормозило.. речь не только о записи данных а проверка на наличие уже в списке

система вин2012 какую бд ставить? mysql 8 ? но есть web-community и просто community... а потом создавать базу через командндую строку или phpmyadmin както ставить ?
в общем подскажите как проще всего что и как поставить. спасибо
У меня на опенсервере около 7 миллионов записей в одной таблице.
Дубли я не проверяю. Просто сделал уникальный индекс по одному полю. Например "домен". Все еще раз такой же домен не добавить.
У меня проблема больше в том что диск обычный не успевает записывать кажись.
Думаю ставить PCI-E диск под БД.
По постнатальным вопросам не знаю.
 
Попробовал по совету @qwerty123 сделать RAM диск.
Что-то стало быстрее, что-то не изменилось. Приходится образ диска сохранять почаще.
Но главное физический диск не насилуется.

Шаблон вначале: подключается к ДБ, блокирует таблицу, берет свободный домен (статус 0), помечает что взят (статус 1), разблокирует таблицу и отключается.
Обрабатывает данные.
В конце: подключается к ДБ, блокирует таблицу, по ID строки обновляет данные, разблокирует таблицу и отключается.

На физ. диске ставил 10 потоков. И это был потолок.
Сейчас 20-30 стабильно, но уже на около 50 вылазит ошибка.

Выполнение действия CSharp OwnCode: Отключаемся от БД. Connection must be valid and open.

Это кубик аварийного разблокирования таблицы и отключения от БД.
шаблон1.png

И все все остальные потоки уходят в ошибку, или не могут обновить данные в конце шаблона.

@WebBot в чем причина ошибки? Поискал по тексту ошибки, везде пишут про conn.Open()

Mysql на основе OpenServer


C#:
Развернуть Свернуть Копировать
[client]

port                            = %mysqlport%
character_sets_dir              = "%dprogdir%\\modules\\database\\%mysql_driver%\\share\\charsets"

[mysql]

no-auto-rehash
no-beep
character_sets_dir              = "%dprogdir%\\modules\\database\\%mysql_driver%\\share\\charsets"

[mysqld]

# Required Settings

basedir                         = "%dprogdir%\\modules\\database\\%mysql_driver%"
bind-address                    = %ip%
character_sets_dir              = "%dprogdir%\\modules\\database\\%mysql_driver%\\share\\charsets"
character_set_server            = utf8mb4
collation_server                = utf8mb4_0900_ai_ci
datadir                         = "%dprogdir%\\userdata\\%mysql_driver%"
default_authentication_plugin   = mysql_native_password
default_storage_engine          = InnoDB
explicit_defaults_for_timestamp = 1
ft_min_word_len                 = 3
local_infile                    = 0
lower_case_table_names          = 1
max_allowed_packet              = 256M
mysqlx                          = 0
pid_file                        = "%dprogdir%\\userdata\\temp\\mysql.pid"
port                            = %mysqlport%
secure-file-priv                = "%dprogdir%\\userdata\\php_upload"
#skip_name_resolve              = 1
ssl                             = 0
tmpdir                          = "%dprogdir%\\userdata\\temp"

# Buffer Settings

bulk_insert_buffer_size         = 8M
join_buffer_size                = 2M
read_buffer_size                = 2M
read_rnd_buffer_size            = 4M
sort_buffer_size                = 2M

# Connection Settings

max_connections                 = 120
max_connect_errors              = 32
back_log                        = 512
thread_cache_size               = 8
interactive_timeout             = 180
wait_timeout                    = 180

# InnoDB Settings

innodb_adaptive_hash_index      = 0
innodb_buffer_pool_instances    = 1
innodb_buffer_pool_size         = 128M
innodb_data_file_path           = ibdata1:10M:autoextend
innodb_data_home_dir            = "%dprogdir%\\userdata\\%mysql_driver%"
innodb_file_per_table           = 1
#innodb_force_recovery          = 1
innodb_log_file_size            = 64M
innodb_read_io_threads          = 8
#innodb_thread_concurrency      = 4
innodb_write_io_threads         = 8

# Logging

%log%general_log                = 1
%log%general_log_file           = "%dprogdir%\\userdata\\logs\\%mysql_driver%_queries.log"
log_error                       = "%dprogdir%\\userdata\\logs\\%mysql_driver%_error.log"
log_bin                         = 0
#log_queries_not_using_indexes  = 1
#long_query_time                = 5
#slow_query_log                 = 1
#slow_query_log_file            = "%dprogdir%\\userdata\\logs\\%mysql_driver%_slow.log"

# MyISAM Settings

key_buffer_size                 = 32M
myisam_max_sort_file_size       = 256M
myisam_recover_options          = backup,force

# Table Settings

table_definition_cache          = 10000
table_open_cache                = 10000
open_files_limit                = 60000
max_heap_table_size             = 128M
tmp_table_size                  = 128M

[mysqldump]

quick
quote_names
max_allowed_packet              = 16M

[myisamchk]

key_buffer_size                 = 64M
sort_buffer_size                = 64M
read_buffer                     = 2M
write_buffer                    = 2M

[mysqlhotcopy]

interactive-timeout

[mysqld_safe]

open_files_limit                = 60000
 
Последнее редактирование:
1) посмотреть в конфиге mysql сколько вообще одновременных подключений разрешено - параметр max_connections
2) выставить в конфеге mysql достаточный wait_timeout - возможно сервер банально разрывает соединение из-за того что нет активности
3) дописать в методы getOne, getRow, getAll, query проверку на валидность соединения перед их выполнением и если не валидно - опять делать open

примерно так
C#:
Развернуть Свернуть Копировать
if ( conn.State != ConnectionState.Open ){
    open();   
}
 
  • Спасибо
Реакции: Shining

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)