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

oOmp

Client
Регистрация
22.01.2018
Сообщения
198
Благодарностей
94
Баллы
28
Нет случайно ни у кого примера как можно профиль сохранить в blob целиком?
Пробовал через LOAD_FILE сделать, но видимо я не до конца что то понимаю, отрабатывает корректно, но ячейка остается пустой.
 

lockerr

Client
Регистрация
20.08.2019
Сообщения
35
Благодарностей
10
Баллы
8
@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 горизонтальных скроллов :-) Пробовал просто строку переносить - не работает :-) ломается запрос

есть такая возможность?
 

oOmp

Client
Регистрация
22.01.2018
Сообщения
198
Благодарностей
94
Баллы
28
По идее для этого надо перенос строк включить.
Скриншот 24-11-2019 190532.jpg
 
  • Спасибо
Реакции: lockerr

lockerr

Client
Регистрация
20.08.2019
Сообщения
35
Благодарностей
10
Баллы
8
@oOmp - включил, не помогло

@WebBot - все сработало! спасибо!
 

Viking01

Client
Регистрация
19.08.2017
Сообщения
228
Благодарностей
151
Баллы
43
Ответ на еще на один вопрос напишу тут, возможно для новичков он так же будет полезен.

Вопрос:
"Вот ты пишешь что если в шаблоне например будет 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
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 774
Благодарностей
1 393
Баллы
113
на версии 5,38,0 через project.Context уже не передает -
var db = project.Context["db"];
возвращает null )
даже через метод project.Context.Add
Проверить не могу, у меня 5.33
Но мои шаблоны где используется БД юзают разные люди и пока никто не сообщал что что-то перестало работать. Контекст используется везде в моих шаблонах.
 

Viking01

Client
Регистрация
19.08.2017
Сообщения
228
Благодарностей
151
Баллы
43
написал в ТП)
 

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 529
Благодарностей
3 375
Баллы
113
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
@WebBot
Что то не хочет стартовать код ((

ЗП 5.22.1

using.png

using1.png

using2.png
 

Koqpe

Client
Регистрация
23.12.2014
Сообщения
1 099
Благодарностей
648
Баллы
113
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63

Koqpe

Client
Регистрация
23.12.2014
Сообщения
1 099
Благодарностей
648
Баллы
113
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
Все разобрался..
Не по глазам были записи в Общем коде они снизу))
db.png
 

Shining

Client
Регистрация
25.05.2018
Сообщения
36
Благодарностей
0
Баллы
6
Как поправить ошибку подскажите плиз: "CSharp OwnCode: db connect. Authentication method 'caching_sha2_password' not supported by any of the available plugins."
Скопировал MySql.Data.dll в папку ExternalAssemblies
 
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
Как поправить ошибку подскажите плиз: "CSharp OwnCode: db connect. Authentication method 'caching_sha2_password' not supported by any of the available plugins."
Скопировал MySql.Data.dll в папку ExternalAssemblies
Mysql 8 кажется используете?
Попробуйте версию по старее использовать.
можно в ПС поискать ;-)
 
  • Спасибо
Реакции: Shining

Kostass

Client
Регистрация
20.12.2010
Сообщения
144
Благодарностей
9
Баллы
18
Подскажите в Версии 5.42 эту проблему так и не пофиксили?
Я сейчас хочу приступить к реализации работы многопотока с БД.
Имеет смысл проделать все выше указаное ?
 
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63

Kostass

Client
Регистрация
20.12.2010
Сообщения
144
Благодарностей
9
Баллы
18
Какую именно проблему?
У меня в шаблоне несколько кубиков подключения, и работы и БД, т.е. при много потоке, я сталнусь с проблемой, что несколько потоком могут брать одну и туже строку из таблицы ?
 
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
У меня в шаблоне несколько кубиков подключения, и работы и БД, т.е. при много потоке, я сталнусь с проблемой, что несколько потоком могут брать одну и туже строку из таблицы ?
Да будет такое, если не помечать строку что она в работе.
Я вышеприведенным кодом пользуюсь, все работает.
 
  • Спасибо
Реакции: Kostass

Porosenok

Client
Регистрация
26.09.2010
Сообщения
1 280
Благодарностей
96
Баллы
48
Подскажите а зачем нам кодом локать таблицу, разве оно само там не локается на стороне БД?

Такая проблема


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

Плюс ко всему я смотрю в трассировке, половина шабов повисла на кубике как раз с мускулем. А зачем на нем виснуть???
 
Последнее редактирование:

Kostass

Client
Регистрация
20.12.2010
Сообщения
144
Благодарностей
9
Баллы
18
Что не так делаю подскажите плизз:
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;
 
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
Что не так делаю подскажите плизз:
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;
А без подстановки переменных работает?
 

Kostass

Client
Регистрация
20.12.2010
Сообщения
144
Благодарностей
9
Баллы
18

qwerty123

Client
Регистрация
26.02.2019
Сообщения
98
Благодарностей
23
Баллы
18
четко доступно с примерами... спасибо .. но прежде чем начать пробывать хотелось бы уточнить:
ориентировочная структура базы простая 3-4 таблицы не больше 5 лямов записей примерно и выполняя парсинг добавлять туда записи с проверкой на дубли или может для таких объемов нету вообще смысла вникать в мускл ? - щас переделал веб парсинг на пост/гет запросы скорость утсраивает/ресурсы освободил ... но вот размер списка спаршенных данных который растет с каждым днем ... незнаю даже.. может ктото поделится опытом сколько список ЗП тянет чтобы не тормозило.. речь не только о записи данных а проверка на наличие уже в списке

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

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

qwerty123

Client
Регистрация
26.02.2019
Сообщения
98
Благодарностей
23
Баллы
18
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
Регистрация
12.07.2014
Сообщения
916
Благодарностей
373
Баллы
63
Попробовал по совету @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
 
Последнее редактирование:

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 774
Благодарностей
1 393
Баллы
113
1) посмотреть в конфиге mysql сколько вообще одновременных подключений разрешено - параметр max_connections
2) выставить в конфеге mysql достаточный wait_timeout - возможно сервер банально разрывает соединение из-за того что нет активности
3) дописать в методы getOne, getRow, getAll, query проверку на валидность соединения перед их выполнением и если не валидно - опять делать open

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

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