ラベル procedures の投稿を表示しています。 すべての投稿を表示
ラベル procedures の投稿を表示しています。 すべての投稿を表示

2014年5月22日木曜日

MySQLの魔法陣の4×4:ルーチン、ループ、変数

Original post: http://anothermysqldba.blogspot.com/2014/05/mysql-magic-square-4x4-routines-loop.html

私は魔方陣で遊んで今日横道それはMySQLのルーチン、ループとか否かをチェックする使用例を与えるために良い機会かもしれないと思ってしまった。 

あなたは魔方陣が何であるかを知らないのであれば、私はいくつかのリンクが含まれている。それはあなたのGoogle検索を保存し、それ以外の例として、数独を考えるかもしれない。 
これもルーチン&ループとIFチェックを使用する方法の例の詳細ですので、私は4×4のマスに魔方陣が限られている。 
私はその方法を示すために日常的に4の値を渡しています。 それは私が一生懸命とにかく4平方コーディングおりますので、不必要なステップですが、それは例のために働く。 

DROP PROCEDURE IF EXISTS magic_sq; 
DROP TABLE IF EXISTS `magic_sq` ; 

delimiter // 
CREATE PROCEDURE magic_sq( N int(11)) 
BEGIN 
DECLARE nXn INT; 
DECLARE SQ_SUM INT; 
DECLARE _passfail_ INT; 
DECLARE min INT; 
DECLARE max INT; 

-- DRAW THE TEMPLATE FOR THE SQUARE MAX of 8 FOR NOW 
DROP TABLE IF EXISTS `magic_sq` ; 
CREATE TABLE `magic_sq` ( 
`xy_id` int(11) NOT NULL AUTO_INCREMENT, 
`1` int(11) NULL DEFAULT NULL, 
`2` int(11) NULL DEFAULT NULL, 
`3` int(11) NULL DEFAULT NULL, 
`4` int(11) NULL DEFAULT NULL, 
PRIMARY KEY (`xy_id`) , 
UNIQUE KEY `Y1` (`1`), 
UNIQUE KEY `Y2` (`2`), 
UNIQUE KEY `Y3` (`3`), 
UNIQUE KEY `Y4` (`4`) 
) ENGINE= MEMORY; 


-- n X n 
SET @nXn = N + N; 
-- SQ_SUM This is the formula for what the total should equal 
SET @SQ_SUM = ( N * (POW(N,2) + 1) ) / 2; 
-- MIN Value 
SET @min=1; 
-- MAX Value 
SET @max=POW(N,2); 

-- BUILD THE SQUARE 
WHILE ( @min <= @nXn ) 
DO 

-- TEST VALUES 
SET _passfail_ = IF ( (@min + (@min +1) + ( @max - 1) +@max) = @SQ_SUM ,1 , 0 ) ; 

-- IF VALID RESULTS THEN SAVE THEM 
IF _passfail_ = 1 THEN 
INSERT INTO magic_sq VALUES (NULL,@min ,(@min +1),( @max - 1) , @max ); 
END IF; 

-- CONTINUE 
SET @min= @min +2; 
SET @max= @max -2; 

END WHILE; 

END// 
delimiter ; 


今私は、ルーチンを内蔵していることを、私は有効な結果を得るのですか? これが可能なすべてのオプション、うまくいくかもしれない単なるオプションではない点に注意してください。 924オプション 4×4の正方形EXISTため。 

CALL magic_sq(4); 
select * from magic_sq; 
+-------+------+------+------+------+ 
| xy_id | 1 | 2 | 3 | 4 | 
+-------+------+------+------+------+ 
| 1 | 1 | 2 | 15 | 16 | 
| 2 | 3 | 4 | 13 | 14 | 
| 3 | 5 | 6 | 11 | 12 | 
| 4 | 7 | 8 | 9 | 10 | 
+-------+------+------+------+------+
 

+-------+---------+ 
| xy_id | per_row | 
+-------+---------+ 
| 1 | 34 | 
| 2 | 34 | 
| 3 | 34 | 
| 4 | 34 | 
+-------+---------+ 
違う! 彼らは、行ではなく列のために働く。 これはルーチン、ループやIF文を使用する方法を示し、例がそれを失敗している間、それは私が何を望むか用意されていません。 だから私は、末尾の場合はチェックの詳細と、挿入だけでなく、スワップいくつかの数字を手直ししなければならなかった。 

DROP PROCEDURE IF EXISTS magic_sq; 
DROP TABLE IF EXISTS `magic_sq` ; 

delimiter // 
CREATE PROCEDURE magic_sq( N int(11)) 
BEGIN 
DECLARE nXn INT; 
DECLARE SQ_SUM INT; 
DECLARE _passfail_ INT; 
DECLARE _io_ INT; 
DECLARE min INT; 
DECLARE max INT; 

-- DRAW THE TEMPLATE FOR THE SQUARE MAX of 8 FOR NOW 
DROP TABLE IF EXISTS `magic_sq` ; 
CREATE TABLE `magic_sq` ( 
`xy_id` int(11) NOT NULL AUTO_INCREMENT, 
`1` int(11) NULL DEFAULT NULL, 
`2` int(11) NULL DEFAULT NULL, 
`3` int(11) NULL DEFAULT NULL, 
`4` int(11) NULL DEFAULT NULL, 
PRIMARY KEY (`xy_id`) , 
UNIQUE KEY `Y1` (`1`), 
UNIQUE KEY `Y2` (`2`), 
UNIQUE KEY `Y3` (`3`), 
UNIQUE KEY `Y4` (`4`) 
) ENGINE= MEMORY; 


-- n X n 
SET @nXn = N + N; 
-- SQ_SUM This is the formula for what the total should equal 
SET @SQ_SUM = ( N * (POW(N,2) + 1) ) / 2; 
-- MIN Value 
SET @min=1; 
-- MAX Value 
SET @max=POW(N,2); 

-- insert_options 
SET _io_ =0; 

-- BUILD THE SQUARE 
WHILE ( @min <= @nXn ) 
DO 

-- TEST VALUES 
SET _passfail_ = IF ( (@min + (@min +1) + ( @max - 1) +@max) = @SQ_SUM ,1 , 0 ) ; 

-- IF VALID RESULTS THEN SAVE THEM 
IF _passfail_ = 1 THEN 

IF _io_ = 0 THEN 
INSERT INTO magic_sq VALUES (NULL,@min ,(@min +1),( @max - 1) , @max ); 
SET _io_ =1; 
ELSEIF _io_ = 1 THEN 
INSERT INTO magic_sq VALUES (NULL,( @max - 1),@max , @min , (@min +1) ); 
SET _io_ =2; 
ELSEIF _io_ = 2 THEN 
INSERT INTO magic_sq VALUES (NULL,@max ,(@min +1) , ( @max - 1) , @min ); 
SET _io_ =4; 
ELSEIF _io_ = 4 THEN 
INSERT INTO magic_sq VALUES (NULL, (@min +1) , @max , @min ,( @max - 1) ); 
SET _io_ =0; 
END IF; 

END IF; 

-- CONTINUE 
SET @min= @min +2; 
SET @max= @max -2; 

END WHILE; 
SELECT @x3y2 := `2` FROM magic_sq WHERE xy_id = 3; 
SELECT @x3y3 := `3` FROM magic_sq WHERE xy_id = 3; 
SELECT @x4y2 := `2` FROM magic_sq WHERE xy_id = 4; 
SELECT @x4y3 := `3` FROM magic_sq WHERE xy_id = 4; 


UPDATE magic_sq SET `2` = @x4y3 , `3` = @x4y2 WHERE xy_id = 3; 
UPDATE magic_sq SET `2` = @x3y3 , `3` = @x3y2 WHERE xy_id = 4; 
select * from magic_sq; 
select SUM(`1`),SUM(`2`),SUM(`3`),SUM(`4`) from magic_sq; 
select xy_id, SUM(`1` +`2` +`3` + `4`) as per_row from magic_sq GROUP BY xy_id; 

END// 
delimiter ;


今、この仕事していますか? 

CALL magic_sq(4); 
+-------+------+------+------+------+ 
| xy_id | 1 | 2 | 3 | 4 | 
+-------+------+------+------+------+ 
| 1 | 1 | 2 | 15 | 16 | 
| 2 | 13 | 14 | 3 | 4 | 
| 3 | 12 | 7 | 10 | 5 | 
| 4 | 8 | 11 | 6 | 9 | 
+-------+------+------+------+------+ 
4 rows in set (0.22 sec) 

+----------+----------+----------+----------+ 
| SUM(`1`) | SUM(`2`) | SUM(`3`) | SUM(`4`) | 
+----------+----------+----------+----------+ 
| 34 | 34 | 34 | 34 | 
+----------+----------+----------+----------+ 
1 row in set (0.22 sec) 

+-------+---------+ 
| xy_id | per_row | 
+-------+---------+ 
| 1 | 34 | 
| 2 | 34 | 
| 3 | 34 | 
| 4 | 34 | 
+-------+---------+ 
[OK]を私はちょうど周りに列を移動することによって、少しだまされていますが、アイデアを得る。

2014年4月26日土曜日

MySQLのパーティションのタイムスタンプ - 日時

Original post: http://anothermysqldba.blogspot.com/2014/04/mysql-partitions-timestamp-datetime.html

だから私は最近、私はまだMySQLのパーティションについてはあまり話していないことに気づきました。
MySQLのパーティション上の多くの良いブログの記事は、すでに存在しており、私は以下のいくつかを記載しております。
私は、次のような状況に遭遇してしまったと私はそれが他の人に役立つことを証明願っています。

timestampデータ型は、しばしば使用されるが、日時はパーティションで良い作品。
(タイムスタンプはないUPDATE CURRENT_TIMESTAMPにNOT NULLにDEFAULT CURRENT_TIMESTAMP)

だから、それをどのようにどのようにこれを修正する例を次に示します。

我々はこの単純なテーブルを持って開始します。

CREATE TABLE `t1` (
`t1_id` int(11) NOT NULL AUTO_INCREMENT,
`field1` varchar(25) DEFAULT NULL,
`field2` int(10) DEFAULT '0',
`time_recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`t1_id`),
KEY `tr` (`time_recorded`)
) ENGINE=InnoDB AUTO_INCREMENT=856964


私たちは、time_recordedフィールド上でパーティションを作成する。 それは、直接にするために、我々は毎月、それを中断します。


ALTER TABLE t1
PARTITION BY RANGE ( TO_DAYS(time_recorded) ) (
PARTITION Jan2014 VALUES LESS THAN (TO_DAYS('2014-02-01')),
PARTITION Feb2014 VALUES LESS THAN (TO_DAYS('2014-03-01')),
PARTITION Mar2014 VALUES LESS THAN (TO_DAYS('2014-04-01')),
PARTITION Apr2014 VALUES LESS THAN (TO_DAYS('2014-05-01')),
PARTITION May2014 VALUES LESS THAN (TO_DAYS('2014-06-01')),
PARTITION Jun2014 VALUES LESS THAN (TO_DAYS('2014-07-01')),
PARTITION Jul2014 VALUES LESS THAN (TO_DAYS('2014-08-01')),
PARTITION Aug2014 VALUES LESS THAN (TO_DAYS('2014-09-01')),
PARTITION Sep2014 VALUES LESS THAN (TO_DAYS('2014-10-01')),
PARTITION Oct2014 VALUES LESS THAN (TO_DAYS('2014-11-01')),
PARTITION Nov2014 VALUES LESS THAN (TO_DAYS('2014-12-01')),
PARTITION Dec2014 VALUES LESS THAN (TO_DAYS('2015-01-01')),
PARTITION Jan2015 VALUES LESS THAN (TO_DAYS('2015-02-01'))
);
ERROR 1486 (HY000): Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed


だから今何を....

さて私は、我々は、パーティションが必要な場合は更新され、主キーを必要とする知っている。

ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (`t1_id`,`time_recorded`), LOCK=NONE;
Query OK, 0 rows affected (38.96 sec)
Records: 0 Duplicates: 0 Warnings: 0

私は、MySQL 5.6を使用していたためであるLOCK = NONEを持っていないことに注意してください
主キーの変更は、私はまだ、データ型を調整する必要があり、私はかかわらず、パーティションを追加することはできません。 今回はSHARED = LOCKEDを使用しています。 詳細については、上記のハイパーリンクを確​​認してください。 あなたが動作しないタイプを選ぶことが起こる場合、通常は実行可能な解決策を提案します。

ALTER TABLE t1 CHANGE time_recorded time_recorded datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, LOCK=SHARED;
Query OK, 854312 rows affected (41.89 sec)
Records: 854312 Duplicates: 0 Warnings: 0


だから今我々は我々のパーティションを追加することができます。

ALTER TABLE t1
-> PARTITION BY RANGE ( TO_DAYS(time_recorded) ) (
-> PARTITION Jan2014 VALUES LESS THAN (TO_DAYS('2014-02-01')),
-> PARTITION Feb2014 VALUES LESS THAN (TO_DAYS('2014-03-01')),
-> PARTITION Mar2014 VALUES LESS THAN (TO_DAYS('2014-04-01')),
-> PARTITION Apr2014 VALUES LESS THAN (TO_DAYS('2014-05-01')),
-> PARTITION May2014 VALUES LESS THAN (TO_DAYS('2014-06-01')),
-> PARTITION Jun2014 VALUES LESS THAN (TO_DAYS('2014-07-01')),
-> PARTITION Jul2014 VALUES LESS THAN (TO_DAYS('2014-08-01')),
-> PARTITION Aug2014 VALUES LESS THAN (TO_DAYS('2014-09-01')),
-> PARTITION Sep2014 VALUES LESS THAN (TO_DAYS('2014-10-01')),
-> PARTITION Oct2014 VALUES LESS THAN (TO_DAYS('2014-11-01')),
-> PARTITION Nov2014 VALUES LESS THAN (TO_DAYS('2014-12-01')),
-> PARTITION Dec2014 VALUES LESS THAN (TO_DAYS('2015-01-01')),
-> PARTITION Jan2015 VALUES LESS THAN (TO_DAYS('2015-02-01'))
-> );
Query OK, 854312 rows affected (50.74 sec)
Records: 854312 Duplicates: 0 Warnings: 0


我々は、SELECT、UPDATE、INSERTおよびパーティションごとなどを削除することができます。 :なお、ここでの詳細https://dev.mysql.com/doc/refman/5.6/en/partitioning-selection.html 。

SELECT COUNT(t1_id) FROM t1 PARTITION (Jan2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 661752 |
+--------------+
1 row in set (0.55 sec)
SELECT COUNT(t1_id) FROM t1 PARTITION (Feb2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 64952 |
+--------------+
1 row in set (0.04 sec)
SELECT COUNT(t1_id) FROM t1 PARTITION (Mar2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 71336 |
+--------------+
1 row in set (0.04 sec)
SELECT COUNT(t1_id) FROM t1 PARTITION (Apr2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 56272 |
+--------------+
1 row in set (0.05 sec)


この作品、私たちは今、パーティションを持っていないが。 我々はまた、現在、パーティションのメンテナンスを考慮しなければなりません。 グリンさんのブログには、自動化されたドロップの非常に良い例を提供し、パーティションの追加。 あなたが例を調整する必要がありますパーティションを削除したくない場合は許可した。
私は私のテーブルの例については、それを調整した。 確認してくださいグリンのブログ詳細については。


DROP PROCEDURE IF EXISTS Rotate_t1_Partition;
DELIMITER ;;
CREATE PROCEDURE Rotate_t1_Partition (newPartValue DATETIME)
BEGIN
-- Setup
DECLARE keepStmt VARCHAR(2000) DEFAULT @stmt;
DECLARE partitionToDrop VARCHAR(64);

-- Find and drop the first partition in the table.
SELECT partition_name
INTO partitionToDrop
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_schema='forums_mysql'
AND table_name='t1'
AND partition_ordinal_position=1;
SET @stmt = CONCAT('ALTER TABLE t1 DROP PARTITION ', partitionToDrop);
PREPARE pStmt FROM @stmt;
EXECUTE pStmt;
DEALLOCATE PREPARE pStmt;

-- Add a new partition using the input date for a value limit.
SET @stmt = CONCAT('ALTER TABLE t1 ADD PARTITION (PARTITION ', DATE_FORMAT(newPartValue - interval 1 MONTH, '%b%Y'), ' VALUES LESS THAN (TO_DAYS(\'', DATE_FORMAT(newPartValue, '%Y-%m-%d'),'\')))');
PREPARE pStmt FROM @stmt;
EXECUTE pStmt;
DEALLOCATE PREPARE pStmt;

-- Cleanup
SET @stmt = keepStmt;
END;;
DELIMITER ;


だから私は、簡単に次のようになりました、このテーブルを更新することができます。

CALL Rotate_t1_Partition('2015-03-01');
Query OK, 0 rows affected (1.11 sec)


のようにしても、できグリンのブログが指摘して、あなたは今、()+区間1ヶ月以上、これまでその時間枠には、パーティションのために決定してこれを使用することができます。 あなたは既にパーティションの日付を渡すと、それが失敗することを心に留めておく必要が付与します。

自動化を続行するには、イベントにこれを追加することができます。

CREATE EVENT Rotate_t1_Partition
-> ON SCHEDULE EVERY 1 MONTH
-> DISABLE ON SLAVE
-> COMMENT 'Remove oldest partition and add a new one '
-> DO
-> CALL Rotate_t1_Partition(NOW() + interval 1 MONTH);
Query OK, 0 rows affected (0.04 sec)


念頭に置いて、上記の例のための有効な時刻を保つ。 私は一例として、これを使用しました。

2014年3月12日水曜日

レビューのためにMySQLのダウンタイムやその他のステータス変数の計画

Original post: http://anothermysqldba.blogspot.com/2014/03/planning-mysql-downtime-and-other.html

我々は、すべての中にMySQLが安定しており、再起動することなく、非常に長い時間実行できることを知っている。 時々、我々はいくつかの変数を調整したりもアップグレードのためにそれを再起動する必要があります。 いくつかは彼らのユーザが眠っているので、一晩これを実行するのに最適な時期であることを前提としてい可能性があります。 しかし、多くの場合、一晩もバックアップと異なるデータマイニング等を行うことができ、他のcrontab関連のスクリプトが含まれてい

それでは、どのようにして、サーバー上で最も活動があるときに指針を得ることができますか? 今、各アプリケーションとデータベースが異なるため、異なる時間枠の間に、実行されている元関連活動に考慮するための要件は。 あ なたが "THREADS_CONNECTED「ステータス変数に5から10分毎分を記録するために開始した場合は、再度、これはあなたのシステムが時間は大丈夫 かもしれませんしたら、すぐにあなたのログインにわたって異なるMySQL接続の量を収集し、時間でロードされた方法によって異なりますフレーム。

これは、多数の方法で行うことができる。 それは、すでに多くの企業レベルのツールで提供され、あなたはスクリプトやなどを書くことができますが、ちょうどMySQLでそれを維持する。 私はこの単純な例のイベントやルーチンを使用します。

簡単な表を作成します。

CREATE TABLE `threads_count` (
`threads_count_id` int(11) NOT NULL AUTO_INCREMENT,
`variable_value` varchar(255) DEFAULT NULL,
`time_recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`threads_count_id`)
) ENGINE=InnoDB;

簡単なルーチンを作成します。

delimiter //
CREATE PROCEDURE threads_tally()
BEGIN
INSERT INTO threads_count SELECT NULL , VARIABLE_VALUE , NOW() FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME IN ('Threads_connected');
END//
delimiter ;

単純なイベントを作成します。

SET GLOBAL event_scheduler = ON;
CREATE EVENT `threads_tally`
ON SCHEDULE EVERY 5 MINUTE
DISABLE ON SLAVE
COMMENT 'keeps a count of Threads_connected'
DO
CALL threads_tally();
DELIMITER ;

今が、上記の例を実装するには、あなたが(おそらくグラフに置くか、または単にレビューのため)から値を選択することができ、テーブルを持つことになりますので、接続数が最も少ないが、サーバー上に存在していたとき、あなたが見ることができます。 アプリケーションやトラフィックに応じて、十分な長さの有効な視点を得るし、イベントを無効にするには実行している、これを維持することができます。

select variable_value , time_recorded FROM threads_count;

今、あなたはもちろん、企業のツールを持っていない場合は、さらに一歩これを取るし、レビューのために自分のステータス変数をすべてのログを保存することができます。

値については、表:

CREATE TABLE `status_review` (
`status_review_id` int(11) NOT NULL AUTO_INCREMENT,
`variable_name` varchar(255) DEFAULT NULL,
`variable_value` varchar(255) DEFAULT NULL,
`time_recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`status_review_id`)
) ENGINE=InnoDB;

値を収集するためのルーチン:

delimiter //
CREATE PROCEDURE status_reviews()
BEGIN
INSERT INTO status_review SELECT NULL , VARIABLE_NAME, VARIABLE_VALUE , NOW() FROM information_schema.GLOBAL_STATUS;
END//
delimiter ;

日常的に実行するイベント:

SET GLOBAL event_scheduler = ON;
CREATE EVENT `status_reviews`
ON SCHEDULE EVERY 1 HOUR
DISABLE ON SLAVE
COMMENT 'keeps a eye on status values'
DO
CALL status_reviews();
DELIMITER ;

あなただけのレビューのために、特定の変数名と値をお勧めしますし、それに応じてルーチンの中でクエリを調整することができます。 実行時間がニーズに依存している、私は、この例では時間を使った。

このコースのそれは時間をかけてこれらのテーブルのうち、関連するいくつかのクリーニングが必要な場合がありますので、もし時間をかけて多くの情報を生成しようとして。 それはすべてあなたがログインして提供された情報を確認する頻度に依存します。

あなたが使用しているため、データの増加、システムの値の多くの着実な増加が表示されている間も、データ内のデータのスパイクを特定し、アプリケーションやシステムの使用にそれを関連付けることができるようになります。

例えばMySQLの企業は、すでにあなたのためにこの種の情報のすべてをグラフ化しますが、これはあなたにも、データの少しの時間と見直しとそれを自分で行うことができる方法です。